Results 1 to 9 of 9
  1. #1
    Join Date
    Feb 2009
    Posts
    4
    Rep Power
    0

    Default Number Array to Sound

    Hello :D

    How do I convert a number array like "int[]" into a playable sound?

  2. #2
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Use the javax.sound.sampled API. Sorry to be so vague, but it's about 50 lines of code, and it's been dealt with here before, so just search the forum.

  3. #3
    Join Date
    Feb 2009
    Posts
    4
    Rep Power
    0

    Default

    I couldn't find anything when I searched the forum but I looked into the javax.sound.sampled API (thanks for the hint).

    I think i'll have to create a Clip using the following constructor:

    public void open(AudioFormat format,
    byte[] data,
    int offset,
    int bufferSize)

    I'll create the audio format using:

    public AudioFormat(float sampleRate, // What's normal?
    int sampleSizeInBits, // What's normal?
    int channels, // 1
    boolean signed, // What's this?
    boolean bigEndian) // What's this?

    I'm stuck on creating the byte[] data. I'm not really sure what I should put here. I know that it will depend a lot on the audioformat so I'm trying to get that out of the way first.

  4. #4
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    This post my help

    Calibration of Sound in Java

  5. #5
    Join Date
    Feb 2009
    Posts
    4
    Rep Power
    0

    Default

    Thanks!

    So far I've got this:

    Java Code:
    float sampleRate = 44000;
    		int sampleSizeInBits = 1;
    		int channels = 1;
    		boolean signed = false;
    		boolean bigEndian = false;
    		AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
    		
    		long lengthinsampleframse = 10;
    		PipedOutputStream outputStream = new PipedOutputStream();
    		PipedInputStream inputStream = new PipedInputStream(outputStream);
    		// PipedInputStream inputStream = new PipedInputStream();
    		// PipedOutputStream outputStream = new PipedOutputStream(inputStream);
    		AudioInputStream audioStream = new AudioInputStream(inputStream,format,lengthinsampleframse);
    		
    		byte[] data = new byte[(int)sampleRate];
    		outputStream.write(data);
    I'm not sure if I create the PipedInputStream with an PipedOutputStream or the other way around. Also how do I play this sound now (assuming that data contains a sound)?

  6. #6
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    That particular post was geared toward creating an mp3 format ed file if I recall. Are you wanting to play directly, or create sound files?

  7. #7
    Join Date
    Feb 2009
    Posts
    4
    Rep Power
    0

    Default

    play directly

  8. #8
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    You have to open a Line using the javax.sound.sample.AudioSystem.getSourceDataLine(A udioFormat) method. Your AudioFormat needs to be set up to tell the audio system all the details about your data.

    I recommend this constructor:

    Java Code:
    AudioFormat(float sampleRate,
                       int sampleSizeInBits,
                       int channels,
                       boolean signed,
                       boolean bigEndian)
    Since this is an int[] created in java, make sure to set bigEndian true.

    Then, you call the open method on your SourceDataLine using the same AudioFormat you constructed to retrieve it from the AudioSystem, and finally, call the write method. The write method requires a byte[]. For int data, you need to convert it to a byte array. To do that, you can use a java.nio.ByteBuffer. Suppose your int sound data was in an array called 'ints'

    Java Code:
    byte[] bytes = new byte[4*ints.length];
    ByteBuffer buf = ByteBuffer.wrap(bytes);
    
    for(int i : ints)
    buf.putInt(ints[i]);
    Now you can call the write method on your SourceDataLine using the array 'bytes'.

  9. #9
    neilcoffey is offline Senior Member
    Join Date
    Nov 2008
    Posts
    286
    Rep Power
    7

    Default Provide the data in the most convenient standard format...

    Quote Originally Posted by Phantasmagorical View Post
    I'm stuck on creating the byte[] data. I'm not really sure what I should put here. I know that it will depend a lot on the audioformat so I'm trying to get that out of the way first.
    It's actually kind of the other way round. You need to get the data into some format that you can conveniently turn it into, and then create an AudioFormat that says what format you've put the data in.

    Unless you want to have to do a sample rate conversion (which to do properly can be slightly complex), the "sample rate" will just be whatever sample rate the data that you have is in. Note that not all sound cards support all possible sample rates. A commonly supported rate is 44100 Hz ("CD quality"[*]).

    Then, if you have no other reason to do anything else, I would:
    (1) scale each of your integers so they're in the range of a short (-32768 to 32767): these are then "16 bit" or 2-byte samples
    (2) allocate a ByteBuffer with a capacity of 2 times the number of samples, and set it to ByteOrder.LITTLE_ENDIAN
    (3) use putShort() to put each sample into your ByteBuffer

    Then calling array() on your ByteBuffer gives you the byte array, and your data is in 16-bits per sample, signed, little-endian (i.e. not big endian) format, so this is what you use in the constructor of AudioFormat. By the way "little/big endian" just refers to which way round the two bytes are in each sample.

    Obviously, you don't need to use the ByteBuffer wrapper if you know how to convert a signed 16-bit number into bytes "manually", but if you're not familiar with bit-twiddling, it probably makes things easier.

    You could obviously decide to use some other format, e.g. 24-bit, unsigned, big-endian etc. But 44100 Hz, signed, 16-bit, little-endian is a very common format and will be supported by most sound cards. (Actually, strictly speaking, I think it's the driver that has to support it!)
    [*] Note that to engineers, "CD quality" means 16-bit 44100 Hz samples timed accurately; not all cheapo sound cards give accurate timing!
    Last edited by neilcoffey; 03-01-2009 at 06:38 PM. Reason: clarification

Similar Threads

  1. Finding the largest number in an array
    By starchildren3317 in forum New To Java
    Replies: 14
    Last Post: 11-03-2010, 07:49 AM
  2. [SOLVED] Array of first negative number
    By random0munky in forum New To Java
    Replies: 9
    Last Post: 12-09-2008, 12:17 AM
  3. Counting the number of columns in a 2D array,
    By KalEl in forum New To Java
    Replies: 9
    Last Post: 10-21-2008, 06:27 AM
  4. initialize a number, which is read in from a file, into an array
    By little_polarbear in forum New To Java
    Replies: 19
    Last Post: 06-10-2008, 04:53 AM
  5. Replies: 8
    Last Post: 04-22-2008, 04:21 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •