1 2 Previous Next 25 Replies Latest reply: Dec 29, 2010 11:10 AM by captfoss RSS

    Display sound data value from ByteArrayOutputStream

    819932
      hi People,

      Can advise what is the function that i can use to retrieve or display the data that i stored in ByteArrayoutputStream buffer?

      So far i can only store the data in... but how can i retrieve and display them on output panel?

      Many Thanks
        • 1. Re: Display sound data value from ByteArrayOutputStream
          sabre150
          Sounds like you need www.jfree.org .
          • 2. Re: Display sound data value from ByteArrayOutputStream
            captfoss
            cielle wrote:
            Can advise what is the function that i can use to retrieve or display the data that i stored in ByteArrayoutputStream buffer?
            Is this a serious question? ByteArrayOutputStream writes data to a byte array... so if you want to read the data, you just read it from the byte[] you used to construct the stream... or wrap said stream in a ByteArrayInputStream...
            • 3. Re: Display sound data value from ByteArrayOutputStream
              819932
              Thank you for your reply. Can advise on below?

              Below is my scenario:
              I wish to display the sound data value (numeric) at the output panel while i am capturing sound from my microphone.
              The program is included with the playback features which is not included in this topic.

              For this purpose, i have a temporary buffer to store the captured sound data temporary from audio dataline.

              class CaptureThread extends Thread{
              byte tempBuffer[] = new byte[10000];

              public void run(){
              byteArrayOutputStream = new ByteArrayOutputStream();

              //Read data from the internal buffer of the data line.
              int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length);

              if(cnt > 0){
              //Save data in output stream object.
              byteArrayOutputStream.write(tempBuffer, 0, cnt);
              System.out.println(byteArrayOutputStream.toString());
              }//end if

              byteArrayOutputStream.close();
              }

              The result that i got is a bunch of unknown character displayed on the output panel. I have gon through the method description for byteArrayOutputStream.toString(). http://download.oracle.com/javase/1.4.2/docs/api/java/io/ByteArrayOutputStream.html
              Suppose it shows the content of buffer.

              The purpose i wish to display the content because i wish to find out the way to retrieve the sound data for Fast Fourier transform.

              Like MATLAB, the sampled sound data (x) can be display with such function
              [x,fs,nb]=wavread("My_love.wav");

              Hereby wish to have your advise how can i get do the same thing of displaying the sound data value with Java.

              Please advise. Many thanks on correcting my mistake.
              • 4. Re: Display sound data value from ByteArrayOutputStream
                793415
                Please read the sticky post at the top of the forum listing. Those posts are there for a reason!
                • 5. Re: Display sound data value from ByteArrayOutputStream
                  819932
                  Hi,

                  Sorry i didn't notice that message at the top of the thread.

                  May i know how can i get to the thread that is stated useful?

                  I can't c the link from there.

                  Thanks!
                  • 6. Re: Display sound data value from ByteArrayOutputStream
                    793415
                    At the top of this page is a link to the Java Sound forum (Java Sound

                    The top post on that forum listing titled 'Announcement: Welcome to the new home' (http://forums.oracle.com/forums/ann.jspa?annID=1405) is the link that I mean.
                    • 7. Re: Display sound data value from ByteArrayOutputStream
                      captfoss
                      cielle wrote:
                      The result that i got is a bunch of unknown character displayed on the output panel. I have gon through the method description for byteArrayOutputStream.toString().
                      http://download.oracle.com/javase/1.4.2/docs/api/java/io/ByteArrayOutputStream.html
                      Suppose it shows the content of buffer.
                      The API says that the toString function "Converts the buffer's contents into a string, translating bytes into characters according to the specified character encoding."

                      You're getting a bunch of unknown characters because it's translating audio data into characters. You don't want characters, you want numbers...
                      Hereby wish to have your advise how can i get do the same thing of displaying the sound data value with Java.
                      There's no automatic way to do that in Java. You have to decode the bytes into the samples yourself based on the format of the data...
                      • 8. Re: Display sound data value from ByteArrayOutputStream
                        819932
                        I have work out the same thing with MATLAB.

                        The sound data i got is a numeric number.
                        If my sampling rate is 44100Hz and i have a 3s recording, i can get (44100*3) 132300 sound data in numeric form.

                        But when i tried to retrieve the sound data with Java, i can't get the numberic form.

                        Can i have your advise, what is the form of sound data in Java so that i can start my coding that deduce the sound data in numeric form?

                        Other than that, can advise how can i start to retrieve the sound data for FFT?? i have done my FFT algoritm in MATLAB, but now i m stuck with ow to retrieve the sound data since i m going to transform my coding from MATLAB to Java...

                        Thanks!
                        • 9. Re: Display sound data value from ByteArrayOutputStream
                          captfoss
                          cielle wrote:
                          Can i have your advise, what is the form of sound data in Java so that i can start my coding that deduce the sound data in numeric form?
                          There isn't "the" format of Sound, JavaSound supports a whole bunch of formats. Specifically, there is a format object associated with your stream that tells you everything you need to know to convert it from a datastream(essentially a byte[]) to a sample stream.

                          You need to know the format first. You get the format by the "getFormat" call to whatever line you're working with, which will return an audio format object.

                          You then just need to do normal byte-to-number conversion, based on the sample size, endianness, signedness of the data, and the number of channels in the stream.

                          The Sample size tells you how many bits are in each sample, so, how much data to use for your byte-to-number conversion. Should be 8 or 16 bit in most cases.

                          The number of channels will tell you how many different sample streams are interleaved. If there is more than one channel in the stream, their samples will be stored one after another...
                          IE

                          RLRLRLRL for a stereo example.

                          So make sure to handle this when you're doing your conversion.
                          • 10. Re: Display sound data value from ByteArrayOutputStream
                            819932
                            Hi, i have google similar reference to change the sound data from byte to integer from my buffer.

                            I am trying to display the sound value at the instant the sound is captured through microphone.

                            I have attempts to modify my code but i got error "java.lang.NullPointerException" ... please advise where is my mistake on my modification.

                            -----------------------------------------------------------------------------------------------
                            Below is part of my code:

                            public int[] ConvertSoundData (byte[] SoundData, int SampleTotal){   <-------- I added this method
                            //Determine the original Endian encoding format
                            boolean isBigEndian = audioFormat.isBigEndian();
                            //this array is the value of the signal at time i*h
                            int x[] = new int[SampleTotal];
                            int value;

                            //convert each pair of byte values from the byte array to an Endian value
                            for (int i = 0; i < SampleTotal*2; i+=2) {
                            int b1 = SoundData;
                                 int b2 = SoundData[i + 1];
                                 if (b1 < 0) b1 += 0x100;
                                 if (b2 < 0) b2 += 0x100;

                                 //Store the data based on the original Endian encoding format
                                 if (!isBigEndian) value = (b1 << 8) + b2;
                                 else value = b1 + (b2 << 8);
                                 x[i/2] = value;
                            }

                            return x;

                            }

                            private AudioFormat getAudioFormat(){
                            float sampleRate = 8000.0F;
                            //8000,11025,16000,22050,44100
                            int sampleSizeInBits = 16;
                            //8,16
                            int channels = 1;
                            //1,2
                            boolean signed = true;
                            //true,false
                            boolean bigEndian = false;
                            //true,false
                            return new AudioFormat(
                            sampleRate,
                            sampleSizeInBits,
                            channels,
                            signed,
                            bigEndian);
                            }//end getAudioFormat

                            class CaptureThread extends Thread{
                            //An arbitrary-size temporary holding buffer
                            byte tempBuffer[] = new byte[10000];

                            public void run(){
                            byteArrayOutputStream = new ByteArrayOutputStream();
                            stopCapture = false;
                            try{//Loop until stopCapture is set by another thread that services the Stop button.
                            while(!stopCapture){
                            //Read data from the internal buffer of the data line.
                            //targetDataLine.read(byte[] b, int off, int len)
                            int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length);

                            if(cnt > 0){
                            float sample_rate = audioFormat.getSampleRate(); <----- I added this command
                            float T = audioInputStream.getFrameLength() / audioFormat.getFrameRate(); <----- I added this command
                            int n = (int) (sample_rate * T ) / 2; <----- I added this command

                            System.out.println(n); <----- I added this command
                            //Save data in output stream object.
                            byteArrayOutputStream.write(tempBuffer, 0, cnt);

                            int[] SoundData = ConvertSoundData(tempBuffer,n); <----- I added this command and following three commands
                            for(int index = 0; index < SoundData.length; index++){
                            System.out.println(SoundData[index]);
                            }

                            }//end if
                            }//end while
                            byteArrayOutputStream.close();
                            }catch (Exception e) {
                            System.out.println(e);
                            System.exit(0);
                            }//end catch
                            }//end run
                            }//end inner class CaptureThread


                            ----------------------------------------------------------------------------------------------------------

                            I have tried to debug on my own. I noticed that
                            float sample_rate = audioFormat.getSampleRate();
                            float T = audioInputStream.getFrameLength() / audioFormat.getFrameRate();
                            cause the problem.
                            I dun understand why it is so since the value is already assigned to the variable.

                            Thanks a lot.

                            N sorry for posting same question on other thread. I will stick with this thread for my problem.
                            • 11. Re: Display sound data value from ByteArrayOutputStream
                              819932
                              Hi again,

                              I have modify my code and found the error.. But this time i can't display the value correctly. Please advise...

                              *-----------------------------------------------------------------------------------------------------------------------------------------------
                              //This method captures audio input from a microphone and saves it in a ByteArrayOutputStream object.
                              private void captureAudio(){
                              try{
                              //Get and display a list of available mixers.
                              Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
                              System.out.println("Available mixers:");
                              for(int cnt = 0; cnt < mixerInfo.length; cnt++){
                              System.out.println(mixerInfo[cnt].getName());
                              }//end for loop

                              //Get everything set up for capture
                              audioFormat = getAudioFormat();

                              DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class,audioFormat);

                              //Select one of the available mixers.
                              Mixer mixer = AudioSystem.getMixer(mixerInfo[3]);

                              //Get a TargetDataLine on the selected mixer.
                              targetDataLine = (TargetDataLine)mixer.getLine(dataLineInfo);
                              //Prepare the line for use.
                              targetDataLine.open(audioFormat);
                              targetDataLine.start();

                              //Create a thread to capture the microphone
                              // data and start it running. It will run
                              // until the Stop button is clicked.
                              Thread captureThread = new CaptureThread();
                              captureThread.start();
                              } catch (Exception e) {
                              System.out.println(e);
                              System.exit(0);
                              }//end catch
                              }//end captureAudio method

                              public int[] ConvertSoundData (byte[] SoundData, int SampleTotal){
                              //Determine the original Endian encoding format
                              boolean isBigEndian = audioFormat.isBigEndian();
                              //this array is the value of the signal at time i*h
                              int x[] = new int[SampleTotal];
                              int value;

                              //convert each pair of byte values from the byte array to an Endian value
                              for (int i = 0; i < SampleTotal*2; i+=2) {
                              int b1 = SoundData;
                                   int b2 = SoundData[i + 1];
                                   if (b1 < 0) b1 += 0x100;
                                   if (b2 < 0) b2 += 0x100;

                                   //Store the data based on the original Endian encoding format
                                   if (!isBigEndian) value = (b1 << 8) + b2;
                                   else value = b1 + (b2 << 8);
                                   x[i/2] = value;
                              }

                              return x;

                              }
                              //This method creates and returns an
                              // AudioFormat object for a given set of format
                              // parameters. If these parameters don't work
                              // well for you, try some of the other
                              // allowable parameter values, which are shown
                              // in comments following the declartions.
                              private AudioFormat getAudioFormat(){
                              float sampleRate = 8000.0F;
                              //8000,11025,16000,22050,44100
                              int sampleSizeInBits = 16;
                              //8,16
                              int channels = 1;
                              //1,2
                              boolean signed = true;
                              //true,false
                              boolean bigEndian = false;
                              //true,false
                              return new AudioFormat(
                              sampleRate,
                              sampleSizeInBits,
                              channels,
                              signed,
                              bigEndian);
                              }//end getAudioFormat
                              //=============================================//

                              //Inner class to capture data from microphone
                              class CaptureThread extends Thread{
                              //An arbitrary-size temporary holding buffer
                              byte tempBuffer[] = new byte[10000];

                              public void run(){
                              byteArrayOutputStream = new ByteArrayOutputStream();
                              stopCapture = false;
                              try{//Loop until stopCapture is set by another thread that services the Stop button.
                              while(!stopCapture){
                              //Read data from the internal buffer of the data line.
                              //targetDataLine.read(byte[] b, int off, int len)
                              int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length);

                              if(cnt > 0){
                              float sample_rate = audioFormat.getSampleRate();


                              float T = audioFormat.getFrameSize() / audioFormat.getFrameRate();
                              int n = (int) (sample_rate * T ) / 2;

                              System.out.println(n); ---------> to print the number of sample
                              //Save data in output stream object.
                              byteArrayOutputStream.write(tempBuffer, 0, cnt);

                              int[] SoundData = ConvertSoundData(tempBuffer,n);
                              for(int index = 0; index < SoundData.length; index++){
                              System.out.println(index + " " + SoundData[index]); ----------> to print the ALL sound data in the returned array.
                              }

                              }//end if
                              }//end while
                              byteArrayOutputStream.close();
                              }catch (Exception e) {
                              System.out.println(e);
                              System.exit(0);
                              }//end catch
                              }//end run
                              }//end inner class CaptureThread


                              *-------------------------------------------------------------------------------------------------------------------------

                              The result i got during i sing "hmmm" to my microphone is as below:

                              1
                              0 1281
                              1
                              0 61184
                              1
                              0 24830
                              1
                              0 25598
                              1
                              0 33279
                              1
                              0 25350
                              1
                              0 19728
                              1
                              0 54537


                              Below is my question:
                              1) Why the number of sample keep on remained as 1? Since the sampling frequency is 8000Hz..
                              2) Why my index variable remained as 0? I suppose i will have 8000 values since my sampling rate is 8000Hz... Is it impossible to print 8000 data within 1 sec?
                              Is it advisable if i transfer the obtained numeric array directly for FFT analysis?

                              (I wish to do a real time frequency analyzer. With MATLAB, I can only do an analyzer by retrieving the .wav data content.)

                              I am shame to say i am still not clear enough with the sampling and data retrieve algorithm. Thats why i will have difficulties to delliver correct idea.
                              Appreciate if you have any tutorial can share with me so that i can understand more.

                              Thank you again.
                              • 12. Re: Display sound data value from ByteArrayOutputStream
                                captfoss
                                Please use the code tags as indicated in the welcome sticky...
                                http://forums.oracle.com/forums/ann.jspa?annID=1405
                                • 13. Re: Display sound data value from ByteArrayOutputStream
                                  captfoss
                                  1) Why the number of sample keep on remained as 1? Since the sampling frequency is 8000Hz..
                                  I assume you're refering to the value you're calculating as N? Because your calculation isn't calculating the sample number...
                                  float T = audioFormat.getFrameSize() / audioFormat.getFrameRate();
                                  int n = (int) (sample_rate * T ) / 2;
                                  audioFormat.getFrameSize is the size of a single frame, for 16-bit that would be 2... audioFromat.getFrameRate is going to be equal to the same rate, which is 8000.

                                  So t = (2/8000).

                                  Sample rate is 8000, so N = (8000 * (2 / 8000)) / 2, which is 1. And it'll always be one, because those numbers don't change... not sure what you were thinking when you wrote that code, honestly...
                                  2) Why my index variable remained as 0? I suppose i will have 8000 values since my sampling rate is 8000Hz... Is it impossible to print 8000 data within 1 sec?
                                  int[] SoundData = ConvertSoundData(tempBuffer,n);
                                  for(int index = 0; index < SoundData.length; index++){
                                  System.out.println(index + " " + SoundData[index]); ----------> to print the ALL sound data in the returned array.
                                  }
                                  You're creating a SoundData equal to length N, which as we previous discussed, is always going to be one. So your loop is, essentially,
                                  for (int index = 0; index < 1; index++)
                                  And it's obvious why your index never gets above 1...
                                  • 14. Re: Display sound data value from ByteArrayOutputStream
                                    819932
                                    Hi thanks for your reply...

                                    May i know what is the different between

                                    audioInputStream.getFrameLength() and audioFormat.getFrameSize() ?

                                    They are not the same?

                                    Suppose that T is he length in seconds of the sample
                                     float T = audioFormat.getFrameSize() / audioFormat.getFrameRate(); 
                                    If i am going to get the length of sample to calculate the number of sample, i should use audioInputStream.getFrameLength() ?

                                    But since i am only extracting the sound data at the time sound is being captured, i can't use audioInputStream as this is used for play back mood, where data is retrieved for SourceDataLine to output the data to speaker.

                                    Thanks again!!

                                    Edited by: cielle on Dec 21, 2010 10:08 PM
                                    1 2 Previous Next