Source
SOURCE download, please first move the android left and right channel control
I mainly use the audiotrack to achieve the control of the left and right channels, mobile phones are generally only two channels, that is, the left channel and the sound channel, we can choose mono when the output, you can also choose two channels (stereo).
See AudioTrack The API, provide,,, and play() pause() stop() write() so on a series of methods.
By write() means of the method, the audio data can be sent out (played out).
Construction of the Audiotrack object
There are three methods of construction
AudioTrack (intintintintintint mode)AudioTrack (intintintintintintintintintint sessionId)
There are several main parameters
Streamtype: Play in what form
- Stream_voice_call
- Stream_system
- Stream_ring
- Stream_music
- Stream_alarm
- Stream_notification
Samplerateinhz: Sample Rate
Channelconfig: Channel
- Audioformat.channel_out_mono: Output mono audio data
- Audioformat.channel_out_stereo: Output dual-channel audio data (stereo)
Audioformat: Audio data format
Mode: Buffered modes
- Mode_static: Once audio is loaded and then played back
- Mode_stream: In the form of a stream, load a bit and play a little
The relevant parameters of the Channelconfig have been looked over, did not find that you can specify to send data to a channel, only through AudioFormat.CHANNEL_OUT_MONO and AudioFormat.CHANNEL_OUT_STEREO choose whether to output mono audio data or two-channel audio data.
Left and right channel control
The specified channel output audio is not selectable at the time of construction, but there is a way
setStereoVolume(floatfloat rightGain)
You can set the volume of one channel to a minimum to achieve the desired output of audio only.
I myself also a bit "hehe", but also did not find that there are other ways to achieve this effect.
This method also has a little problem, on the individual phone, even if the sound of a certain channel is set to the smallest, there will still be a little sound, this I have not yet figured out why, personal speculation may be related to mobile phone hardware.
Packaging
The buffer mode I'm using here is in the MODE_STREAM form of streaming, because this logic is slightly more complicated, especially when pausing to resume playback.
PackageKong.qingwei.androidsoundmanagerdemo;Importandroid.app.Activity;ImportAndroid.media.AudioFormat;ImportAndroid.media.AudioManager;ImportAndroid.media.AudioTrack;ImportAndroid.util.Log;ImportJava.io.ByteArrayOutputStream;ImportJava.io.IOException;ImportJava.io.InputStream;/** * Created by KQW on 2016/8/26. * The thread playing music */ Public class playthread extends Thread { //Sample rate Private intMsamplerateinhz =16000;// Mono Private intMchannelconfig = Audioformat.channel_out_mono;//Dual channel (stereo) //private int mchannelconfig = Audioformat.channel_out_stereo; Private Static FinalString TAG ="Playthread";PrivateActivity mactivity;PrivateAudiotrack Maudiotrack;Private byte[] data;PrivateString Mfilename; Public Playthread(Activity activity, String FileName) {mactivity = activity; Mfilename = FileName;intbuffersize = Audiotrack.getminbuffersize (Msamplerateinhz, Mchannelconfig, audioformat.encoding_pcm_16bit); Maudiotrack =NewAudiotrack (Audiomanager.stream_music, Msamplerateinhz, Mchannelconfig, Audioformat.encoding_pcm_16bit, buffersize, Audiotrack.mode_stream); }@Override Public void Run() {Super. Run ();Try{if(NULL! = Maudiotrack) Maudiotrack.play (); Bytearrayoutputstream Bytearrayoutputstream =NewBytearrayoutputstream (); InputStream InputStream = Mactivity.getresources (). Getassets (). open (Mfilename);//Buffer byte[] buffer =New byte[1024x768];//Playback Progress intPlayindex =0;//Whether the buffer is complete BooleanisLoaded =false;//buffer + play while(NULL! = Maudiotrack && audiotrack.playstate_stopped! = Maudiotrack.getplaystate ()) {//Character length intLenif(-1! = (len = inputstream.read (buffer))) {Bytearrayoutputstream.write (buffer,0, Len); data = Bytearrayoutputstream.tobytearray (); LOG.I (TAG,"Run: Buffered:"+ data.length); }Else{//Buffer completeisLoaded =true; }if(audiotrack.playstate_paused = = Maudiotrack.getplaystate ()) {//TODO has been paused}if(audiotrack.playstate_playing = = Maudiotrack.getplaystate ()) {LOG.I (TAG,"Run: Start from"+ Playindex +"Play"); Playindex + = maudiotrack.write (data, Playindex, Data.length-playindex); LOG.I (TAG,"Run: Played to:"+ Playindex);if(isLoaded && Playindex = = data.length) {LOG.I (TAG,"Run: finished playing"); Maudiotrack.stop (); }if(Playindex <0) {LOG.I (TAG,"Run: Playback error"); Maudiotrack.stop (); Break; }}} log.i (TAG,"Run:play End"); }Catch(IOException e) {E.printstacktrace (); } }/** * Set left and right channel balance * * @param max Max * @param Balance Current value */ Public void setbalance(intMaxintBalance) {floatB = (float) Balance/(float) Max; LOG.I (TAG,"setbalance:b ="+ b);if(NULL! = Maudiotrack) Maudiotrack.setstereovolume (1-B, B); }/** * Set whether the left and right channels are available * * @param left channel *- @param to starboard Channel * / Public void Setchannel(BooleanLeftBooleanright) {if(NULL! = Maudiotrack) {Maudiotrack.setstereovolume (left?1:0, right?1:0); Maudiotrack.play (); } } Public void Pause() {if(NULL! = Maudiotrack) maudiotrack.pause (); } Public void Play() {if(NULL! = Maudiotrack) Maudiotrack.play (); } Public void Stopp() {releaseaudiotrack (); }Private void Releaseaudiotrack() {if(NULL! = Maudiotrack) {maudiotrack.stop (); Maudiotrack.release (); Maudiotrack =NULL; } }}
Play from the beginning
new PlayThread(this"tts1.pcm");mPlayThread.start();
Time out
mPlayThread.pause();
Resume playback after pausing
mPlayThread.play();
Stop playing
null;
Left and right channel control
// 禁用左声道(右声道同理)mPlayThread.setChannel(falsetrue);
Output different audio data separately to left and right channels
is also a very "hehe" approach, but still have not found a better way.
Constructs two AudioTrack objects, outputs two audio respectively, one disables the left channel, one disables the right channel, achieves the expected effect.
new PlayThread(this"tts1.pcm"new PlayThread(this"tts2.pcm");mChannelLeftPlayer.setChannel(truefalse);mChannelRightPlayer.setChannel(falsetrue);mChannelLeftPlayer.start();mChannelRightPlayer.start();
Android left and right channel control