This discussion is archived
5 Replies Latest reply: Feb 15, 2011 4:14 PM by captfoss RSS

Sound is working but doesn't sound correct

839526 Newbie
Currently Being Moderated
I'm using a linux box with the following setup

aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC269 Analog [ALC269 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0

dpkg -l | egrep '(alsa)'|sort
ii alsa-base 1.0.23+dfsg-1ubuntu4 ALSA driver configuration files
ii alsa-oss 1.0.17-4 ALSA wrapper for OSS applications
ii alsa-utils 1.0.23-2ubuntu3.4 Utilities for configuring and using ALSA
ii bluez-alsa 4.69-0ubuntu2 Bluetooth audio support
ii gstreamer0.10-alsa 0.10.30-2 GStreamer plugin for ALSA
ii libsdl1.2debian-alsa 1.2.14-6ubuntu3 Simple DirectMedia Layer (with X11 and ALSA options)
ii libsox-fmt-alsa 14.3.1-1build1 SoX alsa format I/O library

Reported Mixers available to Java:
PulseAudio Mixer
default [default]
Intel [plughw:0,0]
Port Intel [hw:0]

The problem is with my code to generate tones, anything below about 300 Hz is almost inaudible. However if I play a tone with a mp3 player the same 100hz tone booms loudly. I've played with my .asoundrc based on other things I've found on the web, but no luck so far.

Here's my code. Am I doing something wrong with how this is setup?
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;

public class tone {

    public static void play(float freq, float duration) throws LineUnavailableException, IOException {
        float frameRate = 44100f; // 44100 samples/s
        int channels = 2;
        int sampleBytes = Short.SIZE / 8;
        int frameBytes = sampleBytes * channels;
  SourceDataLine SourceDataLine;
  AudioInputStream audioInputStream;

        AudioFormat format =
                new AudioFormat(Encoding.PCM_SIGNED,
                frameRate,
                Short.SIZE,
                channels,
                frameBytes,
                frameRate,
                true);
        int nFrames = (int) Math.ceil(frameRate * duration);
        int nSamples = nFrames * channels;
        int nBytes = nSamples * sampleBytes;
        ByteBuffer data = ByteBuffer.allocate(nBytes);

                Mixer.Info[] mixerInfo =
                    AudioSystem.getMixerInfo();

        try {
            System.out.println("Available mixers:");
            for (int cnt = 0; cnt < mixerInfo.length;
                    cnt++) {
                System.out.println(mixerInfo[cnt].getName());
            }//end for loop
        } catch (Exception e) {
            // nada
        }

        DataLine.Info dataLineInfo =
                            new DataLine.Info(
                            SourceDataLine.class,
                            format);

        Mixer mixer = AudioSystem.
                          getMixer(mixerInfo[0]);
              SourceDataLine = (SourceDataLine)
                     mixer.getLine(dataLineInfo);
      SourceDataLine.open(format);
      SourceDataLine.start();


        int i;
        for (i = 0; i < nFrames; ++i) {
            double value = Math.sin((double) i / (double) frameRate * freq * 2 * Math.PI) * (Short.MAX_VALUE);
            for (int c = 0; c < channels; ++c) {
                int index = (i * channels + c) * sampleBytes;
                data.putShort(index, (short) value);
            }
        }

//        AudioInputStream stream =
//                new AudioInputStream(new ByteArrayInputStream(data.array()), format, nFrames*2);
//        Clip clip = AudioSystem.getClip();
//        clip.open(stream);
//        clip.start();
//        clip.drain();
//        clip.close();
      SourceDataLine.write(data.array(),0,nFrames*2);
      SourceDataLine.drain();
      SourceDataLine.close();
    }
}
Thanks!
Eric

Edited by: sabre150 on 14-Feb-2011 07:21

Moderator action : added [ code] tags so the code is formatted correctly.
  • 1. Re: Sound is working but doesn't sound correct
    sabre150 Expert
    Currently Being Moderated
    On my Linux system using an amplitude of Short.MAX_VALUE results in distortion. I need to drop this down to 16384.0 to stop the distortion. I don't have perfect pitch but middle C (262 Hz) then sounds about right.

    Is there any reason why you use 'float' for the parameters rather than 'double' ? Using 'double' doesn't make anything work better but it saves a load of casting.
  • 2. Re: Sound is working but doesn't sound correct
    839526 Newbie
    Currently Being Moderated
    I guess the low tones could be clipping and making the fundamental frequency so low I can't hear it well. I'll try changing the scale factor.

    I was using double but I've been trying different pieces of code and ideas (you can still see the clip.play stuff commented out). One piece of code was using floats so I switched out part of the code and then just cast it back to double. There's no logic there other than desperation to fix the problem.

    I should mention that I have a lot of audio problems trying to get programs work through ALSA.... There seems to be a common problem getting the java machine to use alsa as a mixer. I'm thinking this is my fundamental problem, but I'll try scaling the sound wave too and report back.

    thanks.
  • 3. Re: Sound is working but doesn't sound correct
    captfoss Pro
    Currently Being Moderated
    http://www.jsresources.org/examples/OscillatorPlayer.html

    Have you tried that, without modification, just inserting the parameters you want?
  • 4. Re: Sound is working but doesn't sound correct
    839526 Newbie
    Currently Being Moderated
    Thanks for all the help. The OscillatorPlayer performs the same as my code.

    The lower notes are almost inaudible (ie anything below about 200 Hz). It's strange because on an mp3 I can hear this tone fine. I tried changing the scaling too, but there was no change in the sound of the tone.

    There must be something funky with my audio setup...it's frustrating. The only thing I've managed to do with .asoundrc was break java's sound all together.

    Well, I'll just keep searching for more info on ALSA and mixer options to see if I can find a clue.
  • 5. Re: Sound is working but doesn't sound correct
    captfoss Pro
    Currently Being Moderated
    Have you tried perhaps doing ULAW instead of LINEAR for the PCM?

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points