Воспроизведение двух звуков Simutaneosly

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

private void playSound(){
       if (mp1 != null) {
           mp1.release(); 
        }
       if (mp2 != null) {
            mp2.release(); 
         }


        mp1 = MediaPlayer.create(this, soundArray[0]); 
        mp2 = MediaPlayer.create(this, soundArray[3]);
        mp1.start();
        mp2.start();

      }

Спасибо


person james    schedule 03.12.2010    source источник
comment
Как вы имеете в виду задержку, это секунды, микросекунды, десять секунд? Насколько близко друг к другу вы хотите, чтобы они игрались, точно в одно и то же время, а не на мгновение раньше?   -  person Patrick    schedule 04.12.2010
comment
Очень короткие ... микросекунды. Я хочу, чтобы они воспроизводились в одно и то же время, да.   -  person james    schedule 04.12.2010
comment
Я имел в виду, что когда они играли, они немного задержались друг с другом. Я просто хочу, чтобы они оба играли в одно и то же время.   -  person james    schedule 04.12.2010
comment
Я остро нуждаюсь в том же. Интересно, как прошло сведение. Есть шанс решения?   -  person Jacek Kwiecień    schedule 20.08.2012


Ответы (5)


Воспроизвести два цифровых звука одновременно так же просто, как сложить их вместе (как в реальном мире), чтобы вы могли сделать это самостоятельно, заполняя буфер (и контролировать время).

Это может привести к увеличению амплитуды, поэтому следует проявлять осторожность, чтобы не выходить за числовые границы типа массива, если вы не хотите вызывать артефакты отсечения.

​​Этот вопрос и ответ также могут быть полезны.

person Emile Vrijdags    schedule 03.12.2010
comment
Спасибо, но кажется продвинутым за мои текущие знания! - person james; 04.12.2010

Делать две вещи одновременно точно… сложно. В однопоточной среде ОС должна переключаться между потоками, чтобы имитировать их одновременную работу. Таким образом, чтобы иметь возможность запускать их «одновременно», вам нужно запустить два потока и дождаться, пока они достигнут точки, в которой они должны быть синхронизированы, а затем позволить обоим потокам теперь, когда они должны продолжить.

Другим решением было бы объединить два звуковых потока так, чтобы это звучало так, как если бы играли два звука, а на самом деле это один. Хотя я не настолько разбираюсь в управлении звуком, и уж точно не на Android ...

Решение для первого - создать два потока, запустить их оба, а затем использовать wait() и notify(), чтобы заставить их одновременно вызывать MediaPlayer.start(), возможно, с помощью Заблокировать класс.


Итак, длинный пример того, как синхронизировать два потока (на основе примера здесь:

import java.util.concurrent.locks.*;

class SynchronizeTest implements Runnable {
    public static void main(String[] args) {
        final ReentrantLock lock = new ReentrantLock();
        final Condition cond = lock.newCondition(); 

        new Thread(new SynchronizeTest(1, lock, cond)).start();
        new Thread(new SynchronizeTest(2, lock, cond)).start();
    }

    private final int number;
    private final ReentrantLock lock;
    private final Condition cond;

    public SynchronizeTest(int number, ReentrantLock lock, Condition cond) {
        this.number = number;
        this.lock = lock;
        this.cond = cond;
    }

    public void run() {
        try {
            if (number == 1) {
                put();
            }
            else {
                take();
            }
        }
        catch (InterruptedException ie) { }
    }

    public void put() throws InterruptedException {
        lock.lock();
        try {
            cond.await();
        } finally {
            lock.unlock();
        }
        System.out.println(number);
    }

    public void take() throws InterruptedException {
        lock.lock();
        // wait for put to take the lock
        Thread.sleep(300);
        try {
            cond.signal();
        } finally {
            lock.unlock();
        }
        System.out.println(number);
    } 
}

Вероятно, это можно закодировать намного проще, но в последнее время я не так много кодировал на Java .. :-(

person Patrick    schedule 03.12.2010
comment
Если это не слишком много проблем или не займет много времени. Может быть, у вас есть какой-нибудь демонстрационный код. Если нет, то все в порядке. Я обнаружил, что использования миди достаточно для моих нужд. - person james; 04.12.2010
comment
@james: К сожалению, нет. Я могу попробовать создать небольшой пример Java (он будет некрасивым), но у меня нет телефона Android, на котором можно было бы его протестировать. - person Patrick; 04.12.2010
comment
@james: Приведен (длинный) пример. Очень много кода только для синхронизации двух потоков, но я предупреждал вас, что это будет некрасиво. ;-) - person Patrick; 04.12.2010

Мне удалось изменить следующее, чтобы заставить это работать. Следует отметить, что это не работало в эмуляторе (они по-прежнему играли один за другим), но после того, как он поместил его на телефон, он отлично заработал.

http://www.droidnova.com/creating-sound-effects-in-android-part-1,570.html

person james    schedule 04.12.2010
comment
извините за вопросы, но я хочу убедиться, что следую вашему решению. так что в конце концов вы только что позвонили; playSound (1); playSound (2); playSound (3); playSound (4); Я лично обнаружил, что это все еще не работает для меня. Можете ли вы объяснить, если вы сделали что-то еще, кроме этого? благодаря. - person YetAnotherDeveloper; 05.12.2010

Я смог получить два звука, играющих одновременно, с помощью класса SoundPool.

person james    schedule 04.12.2010
comment
если вы вызываете их по очереди ... то они действительно не запускаются одновременно, будет очень небольшая задержка. Это позволит звукам перекрываться, но здесь важно время. - person YetAnotherDeveloper; 04.12.2010
comment
если вы нашли решение, можете ли вы обновить свой пост или ответить на свой вопрос? - person YetAnotherDeveloper; 04.12.2010

Организуйте свой код: сначала создайте объекты и загрузите образцы. Затем используйте один метод, чтобы воспроизвести их, а другой, чтобы приостановить / отпустить их.

public class MainActivity extends Activity {

MediaPlayer snd1, snd2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    snd1 = MediaPlayer.create(this, R.raw.s01);
    snd2 = MediaPlayer.create(this, R.raw.s02);
}

public void playSounds(View v) {
    snd1.start();
    snd2.start();
}
public void stopSounds(View v) {
    snd1.pause();
    snd2.pause();
}

}

person Pedro Gonzalez    schedule 20.01.2014