1
votes

Im trying read and store samples from an audio microphone in linux using C/C++. Using PCM ioctls i setup the device to have a certain sampling rate say 10Khz using the SOUND_PCM_WRITE_RATE ioctl etc. The device gets setup correctly and im able to read back from the device after setup using the "read".

int got = read(itsFd, b.getDataPtr(), b.sizeBytes());

The problem i have is that after setting the appropriate sampling rate i have a thread that continuously reads from /dev/dsp1 and stores these samples, but the number of samples that i get for 1 second of recording are way off the sampling rate and always orders of magnitude more than the set sampling rate. Any ideas where to begin on figuring out what might be the problem?

EDIT:

Partial source code:

/////////main loop
while(goforever) {

    // grab a buffer:
    AudioBuffer<uint16> buffer;
    agb->grab(buffer);

    pthread_mutex_lock(&qmutex_data);
    rec.push(buffer);
    pthread_mutex_unlock(&qmutex_data);
    if(tim.getSecs()>=5)
      goforever =false;
}

////////////grab function:

template <class T>
void AudioGrabber::grab(AudioBuffer<T>& buf) const
{

  AudioBuffer<T> b(itsBufsamples.getVal(),
                   itsStereo.getVal() ? 2U : 1U,
                   float(itsFreq.getVal()),
                   NO_INIT);
  int got = read(itsFd, b.getDataPtr(), b.sizeBytes());

  if (got != int(b.sizeBytes()))
    PLERROR("Error reading from device: got %d of %u requested bytes",
            got, b.sizeBytes());

  buf = b;
}
1

1 Answers

3
votes

Just because you ask for a 10kHz sampling rate, it doesn't mean that your hardware supports it. Many sound cards only support one or two sampling rates - mine for example only supports these:

$ grep -rH rates /proc/asound/ | cut -d : -f 2- | sort -u
    rates [0x160]: 44100 48000 96000
    rates [0x560]: 44100 48000 96000 192000
    rates [0x5e0]: 44100 48000 88200 96000 192000

Therefore, you have to check the return value of the SOUND_PCM_WRITE_RATE ioctl() to verify that you got the rate that you wanted, as mentioned here:

SOUND_PCM_WRITE_RATE

Sets the sampling rate in samples per second. Remember that all sound cards have a limit on the range; the driver will round the rate to the nearest speed supported by the hardware, returning the actual (rounded) rate in the argument.