Reputation: 301
I use the android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI intent to load music files from the SD Card.
Intent tmpIntent1 = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(tmpIntent1, 0);
and in onActivityResult
Uri mediaPath = Uri.parse(data.getData().toString());
MediaPlayer mp = MediaPlayer.create(this, mediaPath);
mp.start();
Now MediaPlayer plays the audio in stereo. Is there any way to convert the selected music/audio file or the output from stereo to mono in the app itself?
I looked up API for SoundPool and AudioTrack, but didn't find how to convert mp3 files audio to mono.
Apps like PowerAMP have those Stereo <-> Mono switches that when pressed immediately convert the output audio to mono signal and back again, how do they do it?
Upvotes: 1
Views: 9569
Reputation: 434
First of all, get an encoder to convert your audio file to short array (short[]).
Then convert the short array to mono by splitting the streams.
Then average the split streams.
short[] stereo = new short[BUF_SIZE];
short[] monoCh1 = new short[BUF_SIZE/2];
short[] monoCh2 = new short[BUF_SIZE/2];
short[] monoAvg = new short[BUF_SIZE/2];
stereo = sampleBuffer.getBuffer(); //get the raw S16 PCM buffer here
for( int i=0 ; i < stereo.length ; i+=2 )
{
monoCh1[i/2] = (short) stereo[i];
monoCh2[i/2] = (short) stereo[i+1];
monoAvg[i/2] = (short) ( ( stereo[i] + stereo[i+1] ) / 2 );
}
Now you have:
PCM mono stream from channel 1 (Left channel) in monoCh1
PCM mono stream from channel 2 (Right channel) in monoCh2
PCM mono stream from averaging both channels in monoAvg
Upvotes: 1
Reputation: 314
Do you load .wav- files respectively PCM- data? If so then you could easily read each sample of each channel, superpose them and divide them by the amount of channels to get a mono signal.
If you store your stereo signal in form of interleaved signed shorts, the code to calculate the resulting mono signal might look like this:
short[] stereoSamples;//get them from somewhere
//output array, which will contain the mono signal
short[] monoSamples= new short[stereoSamples.length/2];
//length of the .wav-file header-> 44 bytes
final int HEADER_LENGTH=22;
//additional counter
int k=0;
for(int i=0; i< monoSamples.length;i++){
//skip the header andsuperpose the samples of the left and right channel
if(k>HEADER_LENGTH){
monoSamples[i]= (short) ((stereoSamples[i*2]+ stereoSamples[(i*2)+1])/2);
}
k++;
}
I hope, I was able to help you.
Best regards, G_J
Upvotes: 3