Playing two sounds Simutaneosly

2020-03-02 04:59发布

问题:

I am trying to play two sounds simutaneosly in android.I have created two MediaPlayers and am using the code below.They are currently playing one after another.Or not exactly one after another but kinda delayed into eachother.

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();

      }

Thanks

回答1:

Playing two digital sounds simultaneously is as simple as summing them together (as in the real world), so you could do that yourself while filling the buffer (and have control over timing).

This could cause the amplitude to raise, so care should be taken to not surpass the numeric bounds of the array type if you don't want to cause clipping artifacts.

This question and answer might also be helpful



回答2:

Doing two things at exactly the same time is ..difficult. In a one threaded environment the OS needs to jump between threads to simulate them running at the same time. So to be able to run them at the "same time", you need to start two threads and wait for them to arrive at the point where they should be synchronized and then let both threads now that they should continue.

Another solution would be to merge the two sound streams so that it sounds like if it's two sounds playing when it's actually one. Altough I'm not that proficient in sound manipulation, and definitely not on Android...

A solution for the first would be to spawn two threads, start them both and then use a wait() and notify() to get them to call MediaPlayer.start() at the same time, possibly with the Lock class.


Okay, so a long example of how to synchronize two threads (based on example here are:

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);
    } 
}

This can probably be coded much simpler, but I haven't done that much Java coding lately.. :-(



回答3:

I was able to modify the following to get this to work.It should be noted that it did not work in the emulator(they still played one after another), but after putting it on the phone it worked great.

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



回答4:

I was able to get two sounds Playing At the exact same time by using the SoundPool class.



回答5:

Organize your code: Create the objects and load the samples first. Then use one method to play them, and another to pause/release them.

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();
}

}