Sound conversion problem using javax.sound......

Hello,

I have a situation, i have data and source sound format. For example, if i wand to process .MP3 file then format of the data like bitRate, sample rate, channels etc. have in the one object (You can consider that object as like simple object containing getter/setter for all properties). And, all related data in another object/file (Like in byte array). I have both format and data separate not in same file like normal .MP3 file.

Know i want to convert that data in to PCM format so that i can play using the javax.sound… package classes…

If any one have idea then its most welcome.
Any help would be appreciated…

Thanks In Advance

Hey, There is no solution for this problem…?

JLayer is an MP3 decoder in java so maybe you can use that.
I’m not completely understanding why or how you have your data separated from the format data, but if your separated files are still based on mp3 you might have to adapt JLayer to your needs (it’s open source). Or roll your own…

Hello,

  I have one application that originally written in to the C++, that application access the video data from our hand written server. That server work like RTP server. In abstract, server first sends the audio data format (It may be in any format like PCM OR compressed using any of the technique), then sends the audio data in given format. The client application convert that audio data in to PCM if it is not in that format and plays it. 

 Know we are converting the client application in to the Java, server application is same, not changed. Hence, we have to achieve same functionality in Java.

By default windows has in built API/Functions to convert a different sound format in to PCM format.

But, how i can do that in java…?

Thanks and Regards

You might want to read about Java Sound SPI.
Per default, JavaSound doesn’t support many formats, so you need extensions in the form of an ‘SPI’ (Service Provider Interface) to get support for additional formats like MP3.

http://java.sun.com/docs/books/tutorial/sound/
http://www.javaworld.com/javaworld/jw-11-2000/jw-1103-mp3.html
http://www.javazoom.net/mp3spi/mp3spi.html

Hello erikd,

   Thanks for suggestion....
   
  Following is a audio format class which i am getting from the server. That represents the format of the data.

                   
                   WaveFormatEX waveFormat = new WaveFormatEX();
		waveFormat.wBitsPerSample = 16;
		waveFormat.nBlockAlign = 1;
		waveFormat.nAvgBytesPerSec = 2000;
		waveFormat.nSamplesPerSec = 11025;
		waveFormat.wFormatTag = 85;    /// What is this ?
		waveFormat.nChannels = 1;		
		waveFormat.cbSize = 12;	 // What is this ?
		waveFormat.exData = new byte[12]; 

Above is one of the data format i am getting. The sound is some how compressed.
The original file is .wav but when i opened its property it shows Audio Format - MPEG LAYER - 3

Now from above information i want to create javax.sound.sampled.AudioFormat object.

Do you have any suggesting for that…?

Thanks and Regards

Ok, I’m beginning to understand your problem now.

WAVEFORMATEX is a Windows specific struct which describes an audio stream.
wFormatTag is an enumeration of the audio format, which can be things like PCM, MP3, whatever. The value 85 probably means MP3 in your case.
cbSize is the size of exData, which stores more properties about wFormatTag.

Read more about it here:
http://msdn.microsoft.com/en-us/library/ms789667.aspx
http://dn.codegear.com/fi/print/21300

The problem is that this is Windows specific data, so there’s no standard API in java to handle it.
If I were you, I’d first assume MP3 and just try to use JLayer to play the stream associated with this WAVEFORMATEX struct. Not sure if that’s going to work immediately, you might need to use some of the struct’s data for example to be able to parse the stream, but I also wouldn’t be at all surprised if it does Just Work in the case of MP3…

Hello,

  Thanks for help... 

  I have another problem, how i can mix sound balance and volume?. In Java, there are some controls like float control using that i can change volume and balance of the SourceDataLine (javax.sound.sampled). But here i have different situation. I have more than one SourceDataLine opened and all are playing individual audio file (Streams).  I have to changed volume and balance (Sterio sound) of only one stream. I mean balancing effect should come on only one stream, other stream should not get effect of balance and volume. 

If i use Java float control then it would affect all playing streams/file. 

Do you have any idea…?

Thanks and Regards

It seems like you’re using the Controls from the mixer, not the individual Lines?

Hello,

     I have individual lines to play all audio files. Does control from all line behave independently...?

My understanding is that you query a Line for available Controls, but a Mixer is also a Line.
So I’d guess that if you get a Control from a Mixer, you’ll get a global Control for all it’s lines whereas if you’d get a Control from an individual Line, it should work independently.

I’d have to check to be sure (haven’t tried it in a long time), but IIRC this is how it works.

Hello,

    you are correct, lines from the mixer returns individual controls and does not affects other lines. 

   But the problem is that it does not set the sound and balance uniformaly, it sets step by step like jumping style.....

Regards

How are you updating the Controls? If you’re updating controls using a GUI, that might be the problem, which you could solve with interpolation.

EDIT: This topic is starting to get offtopic… So were you able to play your MP3 stream in the meantime? :slight_smile:

Hello,

:slight_smile:

I now able to play the MP3 stream.
Here the process what i have done to play that.

I have downloaded the MP3 SPI suggested by you and registered it. Now, i am generating one WAV file using audio format and audio data sent by the server. I am creating a file that is in same format as windows WAV file format (http://ccrma.stanford.edu/courses/422/projects/WaveFormat/). We can play that generated file using the javax.sound classes.

Another process, if you have a audio data in the file and MP3 SPI registered, you can directly get AudioInputStream using AudioSystem.getAudioInputStream(InputStream stream) method. It automatically analyse the data and determine the format of that data.

Thanks and Regards

Good to hear! :slight_smile:

Hello,

 Can i change a sound balance by changing a row sound data....? I means bytes of the audio input stream.

Thanks and Regards

Hello,

    i got some success in changing the sound volume and balance by shifting the row bits. Here is the code snap shots

	for(int Icount=0;Icount<size;Icount+=2){
		int b =  ((buffer[Icount+1] << 8 ) | (buffer[Icount] & 0xFF)) & 0xFFFF;
		if(Jcount%2==0){
			b = (b * 0)>> 15;
			Jcount = 1;
		}
		else{
			b = (b * 32768)>> 15;
			Jcount = 0;
		}
		if(b<0){
			out.println(b);
		}
		buffer[Icount] = (byte) (b & 0xff);
		buffer[Icount+1] = (byte) ((b & 0xff00)>>8 );			
	}

This code is in loop where Icount start from 0…buffer.length…

The problem is that it generates some noise.

Can you help me for that?

Thanks and Regards

I’m not sure what this code is supposed to do, but I notice the following:

b = (b * 0)>> 15;

is basically the same as

b = 0;

and

b = (b * 32768)>> 15;

is the same as

b = b;

so it’s a redundant line that’s doing nothing.

What is Jcount used for?

b = (b * 0)>> 15; is for left channel, it masks all bits so that left chennel will not have sound.

b = (b * 32768)>> 15; is for right channel. If we increase multiplyer (32768) sound will high on corresponding channel.

Jcount is used just to swith between left and right channel. See. if(Jcount%2==0){

What erikd is getting at, is the above loop is (unintentionally?) ~equivalent to the much simpler loop :-


assert Jcount==0 || Jcount==1; // because the above code example doesn't give the initial value of Jcount
for(int Icount=0;Icount<size;Icount++){
if( (lcount/2)%2==Jcount) {
   buffer[lcount] = 0;
}
}