2015-07-29 43 views
8

Một số trường hợp đặc biệt buộc tôi phải làm điều đó.Phát 2 luồng âm thanh khác nhau trên loa trái và phải

Có thể phát 2 luồng âm thanh khác nhau trên các kênh khác nhau không. Hãy tưởng tượng một tai nghe và tôi cần phải chơi bài hát đầu tiên ở loa trái và bài hát thứ 2 trên loa phải cùng một lúc.

Sau một số nghiên cứu tôi thấy rằng có thể phát ở một số kênh đơn lẻ. Thậm chí có thể đóng một trong số chúng. Nhưng tôi không tìm thấy bất kỳ thông tin nào về cách phát 2 luồng âm thanh cùng một lúc.

Thậm chí có thể không? Và làm thế nào? Một số ví dụ mã và liên kết được đánh giá cao!


Kết quả nghiên cứu.

1)AudioTrack thể chơi trên các kênh khác nhau

// only play sound on left 
for(int i = 0; i < count; i += 2){ 
    short sample = (short)(Math.sin(2 * Math.PI * i/(44100.0/freqHz)) * 0x7FFF); 
    samples[i + 0] = sample; 
    samples[i + 1] = 0; 
} 
// only play sound on right 
for(int i = 0; i < count; i += 2){ 
    short sample = (short)(Math.sin(2 * Math.PI * i/(44100.0/freqHz)) * 0x7FFF); 
    samples[i + 0] = 0; 
    samples[i + 1] = sample; 
} 

2)SoundPool thể thiết lập âm lượng cho các kênh trái và phải riêng biệt. Vì vậy, về mặt kỹ thuật, có thể bắt đầu 2 luồng và đặt cho một lượng 0 trái và 100 cho âm lượng phù hợp và ngược lại cho luồng thứ 2. Đúng?

setVolume(int streamID, float leftVolume, float rightVolume) 

mẫu:

SoundPool pool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); 
pool.play(
     pool.load(this, R.raw.my_sound_effect, 1), // The sound effect to play 
     0, // The volume for the left channel (0.0 - 1.0) 
     1.0f, // The volume for the right channel (0.0 - 1.0) 
     0, // Default priority 
     0, // Do not loop 
     1.0f); // Playback rate (1.0f == normal) 

Perhabs có giải pháp như sử dụng MediaPlayer do đó sẽ là thích hợp hơn nhiều!


SOLUTION: Có vẻ như là giải pháp đơn giản nhất là sử dụng SoundPool. Cách tôi thử nghiệm nó.

//SDK Version 
public CustomSoundPool() { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     AudioAttributes attributes = new AudioAttributes.Builder() 
       .setUsage(AudioAttributes.USAGE_GAME) 
       .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 
       .build(); 

     soundPool = new SoundPool.Builder() 
       .setAudioAttributes(attributes) 
       .build(); 
    } else { 
     soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); 
    } 
    soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { 
     @Override 
     public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { 
      soundPool.play(sampleId, 1.0f, 0, 0, 0, 1.0f); //left channel 
      //soundPool.play(sampleId, 0, 1.0f, 0, 0, 1.0f); //right channel 
     } 
    }); 
} 

public void playSound(String path) { 
    if (soundPool != null) { 
     soundPool.load(path, 1); 
    } 
} 

public void release(){ 
    if (soundPool != null) { 
     soundPool.release(); 
    } 
} 

Mặc dù thiếu các tính năng như MediaPlayer.OnCompletionListener(). Bây giờ chắc chắn làm thế nào để thực hiện điều này nhưng dù sao .. Vấn đề được giải quyết.

Trả lời

2

Hoặc cách tiếp cận 1) 2) sẽ hoạt động như bạn đã nói.

Về phương pháp 1), nếu bạn muốn phát các luồng khác nhau cùng một lúc, bạn có thể viết cả hai kênh với dữ liệu khác nhau trong cùng một vòng lặp mà không sử dụng hai vòng lặp. Để đặt âm lượng cho mỗi kênh, bạn có thể sử dụng phương thức AudioTracksetStereoVolume(float leftGain, float rightGain).

Kể từ MediaPlayer là API cấp cao, nó không cung cấp mức độ cụ thể này; giải pháp có thể là lưu dữ liệu âm thanh vào một tệp (tắt kênh trái/phải) và phát nó làm phần tử phương tiện thông thường sử dụng MediaPlayer.


UPDATE:

lưu dữ liệu âm thanh vào một tập tin (tắt tiếng các kênh trái/phải)

Để làm điều này, giả định rằng bạn có dữ liệu âm thanh của bạn trong AudioTrack định dạng tương thích (PCM), bạn chỉ cần xử lý dữ liệu như bạn đã nói (tắt một kênh bằng cách đặt lại một phần của mảng) và sau đó lưu mảng/bộ đệm vào một tệp dưới dạng WAV/PCM. Hãy xem here để biết thêm chi tiết và mã về cách lưu tệp WAV.

+0

_lưu dữ liệu âm thanh vào tệp (tắt kênh trái/phải) ._ Bạn có thể giải thích cách thực hiện điều đó bằng mẫu mã không? – AnZ

+0

@AnZ Tôi đã cập nhật câu trả lời của mình. Dù sao tôi đề nghị sử dụng các phương pháp AudioTrack/SoundPool tinh khiết thay vì phương pháp MediaPlayer. – bonnyz

+0

Tôi thử phương pháp đầu tiên của bạn với hai bản âm thanh, một bản nhạc đã để lại âm lượng 0 và âm lượng phải 1 và ngược lại cho một bản âm thanh khác. Nhưng khi tôi viết đồng thời, nó không chơi cùng một lúc. Có rất ít sự khác biệt về thời gian. ' –

Các vấn đề liên quan