Android: микширование звука - PullRequest
3 голосов
/ 10 января 2012

Я занимаюсь разработкой приложения для Android, которое записывает голос с помощью медиа-рекордера и воспроизводит музыку с помощью медиаплеера.

Моя цель - сделать возможным объединение двух аудио в один файл, поскольку Android не предлагает никакого APIдля этого я ищу разумное решение.

В данный момент во время воспроизведения я использую новый медиа-рекордер с источником MIC для захвата звука и его сохранения, но это очень плохо !!!

В любом случае, чтобы смешать аудио?включая какое-либо собственное решение lix SOX или FFMPEG?

Или, во всяком случае, записывать в файл, используя вместо этого вывод медиаплеера вместо использования MIC?

Любое предложение приветствуется.

Спасибо.

1 Ответ

1 голос
/ 13 августа 2014

Когда я столкнулся с той же проблемой, я смог найти решение для смешивания файлов. Поскольку смешивание двух 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 = new DataInputStream (new 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();

  }

здесь path1 и path2 - это путь к wav-файлу, который вы хотите смешать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...