audio stream sampling rate in linux
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()>=开发者_JS百科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;
}
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.
精彩评论