2012-01-10 118 views
3

我正在開發一款使用mediarecorder錄製語音並使用mediaplayer播放音樂的Android應用程序。Android:混合音頻

我的目標是使兩個音頻混合成一個文件成爲可能,並且由於Android不提供任何API,我正在尋找合理的解決方案。

在播放的時候,我正在使用一個帶MIC源的新型錄音機來捕捉音頻並保存它,但是這非常差!

無論如何混音?包括任何本地解決方案lix SOX或FFMPEG?

或者,無論如何,要錄音機到文件使用作爲源mediaplayer輸出,而不是使用MIC?

任何建議表示感謝。

謝謝。

回答

1

當我遇到同樣的問題時,我能夠找到一個混合文件的解決方案。 由於無法混合兩個mp3文件,因此您必須先將其轉換爲波形格式,然後設置標題值。然後添加數據字段。我以下面的方式做了這個。希望我的代碼能幫助你。

類MixFile延伸的AsyncTask {

ProgressDialog dialog; 
    protected void onPreExecute() { 
     dialog= new ProgressDialog(MainActivity.this); 
     dialog.setCancelable(false); 
     dialog.setMessage("Mixing two wav files"); 
     dialog.show(); 
    } 
    @Override 
    protected Void doInBackground(Void... arg0) { 
     short[] audioData1 = null; 
     short[] audioData2 = null; 

     int n = 0; 

     try { 
      DataInputStream in1; 

// IN1 =新DataInputStream類(新的FileInputStream(Environment.getExternalStorageDirectory()+ 「/Soundrecpluspro/one.wav」)); in1 = new DataInputStream(new FileInputStream(path1)); ByteArrayOutputStream bos = new ByteArrayOutputStream();

  try { 

       while ((n = in1.read()) != -1) { 
        bos.write(n); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray()); 
      bb.order(ByteOrder.LITTLE_ENDIAN); 
      ShortBuffer sb = bb.asShortBuffer(); 
      audioData1 = new short[sb.capacity()]; 

      for (int i = 0; i < sb.capacity(); i++) { 
       audioData1[i] = sb.get(i); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     try { 
      DataInputStream in1; 
      in1 = new DataInputStream(new FileInputStream(path2)); 
      ByteArrayOutputStream bos = new ByteArrayOutputStream(); 

      try { 

       while ((n = in1.read()) != -1) { 
        bos.write(n); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 


      ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray()); 
      bb.order(ByteOrder.LITTLE_ENDIAN); 
      ShortBuffer sb = bb.asShortBuffer(); 
      audioData2= new short[sb.capacity()]; 

      sb.get(audioData2); 


      System.out.println(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     // find the max: 



     float max = 0; 

     Log.d("File audio lenght 1 ", ""+audioData1.length); 
     Log.d("File audio lenght 2 ", ""+audioData2.length); 

     System.out.println("MainActivity.MixFile.doInBackground() 1"+audioData1.length); 
     System.out.println("MainActivity.MixFile.doInBackground() 2"+audioData2.length); 

     if(audioData1.length > audioData2.length){ 

     for (int i = 22; i < audioData2.length; i++) { 
      if (Math.abs(audioData1[i] + audioData2[i]) > max) 
       max = Math.abs(audioData1[i] + audioData2[i]); 
     } 

     System.out.println("" + (Short.MAX_VALUE - max)); 
     int a, b, c; 
     // now find the result, with scaling: 
     for (int i = 22; i < audioData2.length; i++) { 
      a = audioData1[i]; 
      b = audioData2[i]; 

      c = Math.round(Short.MAX_VALUE * (audioData1[i] + audioData2[i]) 
        /max); 

      if (c > Short.MAX_VALUE) 
       c = Short.MAX_VALUE; 
      if (c < Short.MIN_VALUE) 
       c = Short.MIN_VALUE; 


      audioData1[i] = (short) c; 

     } 

     // to turn shorts back to bytes. 
     byte[] end = new byte[audioData1.length * 2]; 
     ByteBuffer.wrap(end).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioData1); 

     try { 
      OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/assets/mixer12.wav"); 
      for (int i = 0; i < end.length; i++) { 
       out.write(end[i]); 
       out.flush(); 
      } 
      out.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     }else{ 

      System.out.println("MainActivity.MixFile.doInBackground() smaller one"); 
      for (int i = 22; i < audioData1.length; i++) { 
       if (Math.abs(audioData2[i] + audioData1[i]) > max) 
        max = Math.abs(audioData2[i] + audioData1[i]); 
      } 

      System.out.println("" + (Short.MAX_VALUE - max)); 
      int a, b, c; 
      // now find the result, with scaling: 
      for (int i = 22; i < audioData1.length; i++) { 
       a = audioData2[i]; 
       b = audioData1[i]; 

       c = Math.round(Short.MAX_VALUE * (audioData2[i] + audioData1[i]) 
         /max); 

       if (c > Short.MAX_VALUE) 
        c = Short.MAX_VALUE; 
       if (c < Short.MIN_VALUE) 
        c = Short.MIN_VALUE; 


       audioData2[i] = (short) c; 

      } 

      // to turn shorts back to bytes. 
      byte[] end = new byte[audioData2.length * 2]; 
      ByteBuffer.wrap(end).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioData2); 

      try { 
       OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/Assets/mixer1.wav"); 
       for (int i = 0; i < end.length; i++) { 
        out.write(end[i]); 
        out.flush(); 
       } 
       out.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 



     } 
     return null; 
    } 

和活動我把它叫做如下

public class MainActivity extends Activity implements OnClickListener { 

    new MixFile().execute(); 

    } 

這裏路徑1和路徑2是要混合

wav文件的路徑