2012-01-10 3 views
3

mediarecorder를 사용하여 음성을 녹음하고 mediaplayer를 사용하여 음악을 재생하는 Android 앱을 개발 중입니다.Android : 오디오 믹싱

내 목표는 두 개의 오디오를 하나의 파일로 믹싱하는 것이고 Android는 API를 제공하지 않으므로 합리적인 해결책을 찾고 있습니다.

재생 시간에 나는 오디오를 캡처하고 저장하기 위해 마이크 소스가있는 새 mediarecorder를 사용하고 있지만 이것은 매우 열악합니다 !!!

어쨌든 오디오를 믹스 하시겠습니까? 모든 원시 솔루션 lix SOX 또는 FFMPEG를 포함하여?

또는 어쨌든 미디어 플레이어 출력 대신 원본을 사용하여 파일을 레코딩하려면 MIC를 사용 하시겠습니까?

의견을 보내 주시면 감사하겠습니다.

감사합니다.

답변

1

같은 문제에 직면했을 때 파일을 혼합하기위한 솔루션을 찾을 수있었습니다. 2 개의 mp3 파일을 믹싱 할 수 없으므로 먼저 웨이브 형식으로 변환 한 다음 데이터 필드를 추가하는 헤더 값 .after를 설정해야합니다. 나는 이것을 다음과 같이했다. 내 코드가 도움이되기를 바랍니다.

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 = 새 DataInputStream (새 FileInputStream (경로 1)); 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 파일의 경로입니다
관련 문제