частота дискретизации аудиопотока в linux

Я пытаюсь читать и сохранять образцы с аудиомикрофона в Linux, используя C/C++. Используя ioctl PCM, я настраиваю устройство на определенную частоту дискретизации, скажем, 10 кГц, используя ioctl SOUND_PCM_WRITE_RATE и т. Д. Устройство правильно настраивается, и я могу считывать с устройства после настройки с помощью «чтения».

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

У меня проблема в том, что после установки соответствующей частоты дискретизации у меня есть поток, который постоянно читает из /dev/dsp1 и сохраняет эти сэмплы, но количество сэмплов, которые я получаю за 1 секунду записи, далеко от частоты дискретизации и всегда на несколько порядков больше установленной частоты дискретизации. Любые идеи, с чего начать, выясняя, в чем может быть проблема?

РЕДАКТИРОВАТЬ:

Частичный исходный код:

/////////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;
}

person farhan    schedule 31.01.2011    source источник


Ответы (1)


То, что вы запрашиваете частоту дискретизации 10 кГц, не означает, что ваше оборудование поддерживает ее. Многие звуковые карты поддерживают только одну или две частоты дискретизации — моя, например, поддерживает только эти:

$ 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

Поэтому вам необходимо проверить возвращаемое значение SOUND_PCM_WRITE_RATE ioctl(), чтобы убедиться, что вы получили нужный курс, как указано здесь:

SOUND_PCM_WRITE_RATE

Устанавливает частоту дискретизации в выборках в секунду. Помните, что все звуковые карты имеют ограничение на диапазон; драйвер будет округлять скорость до ближайшей скорости, поддерживаемой аппаратным обеспечением, возвращая фактическую (округленную) скорость в качестве аргумента.

person thkala    schedule 31.01.2011
comment
Я проверил это, и звуковая карта совместима с настройками скорости, которые я настроил, кроме того, выполнив ioctl SOUND_PCM_READ_RATE, я могу прочитать установленную скорость, и она работает нормально. После дальнейшего тестирования я обнаружил, что каким-то образом я получаю повторение блоков, считываемых из /dev/dsp1, как будто после того, как я прочитал данные, они не отрываются от буфера. Я не знаю, почему это так? - person farhan; 01.02.2011
comment
да, одноканальное моно с использованием SOUND_PCM_WRITE_CHANNELS ioctl - person farhan; 01.02.2011
comment
Должен ли я предположить, что вы также проверили это возвращаемое значение, и что биты/выборка также установлены и проверены? - person thkala; 01.02.2011
comment
Да, кажется, все настроено правильно и не возвращает отрицательных значений. SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS, SOUND_PCM_READ_RATE, SNDCTL_DSP_GETBLKSIZE — все они возвращают правильные значения. - person farhan; 01.02.2011
comment
@farhan: вы можете попробовать использовать strace, например. sox, так как он записывает со звуковой карты. Вы также можете попробовать опубликовать свой реальный код - возможно, у вас где-то есть ошибка. - person thkala; 01.02.2011
comment
Код немного длинный, но я могу включить важные части, которые вы можете увидеть здесь: pastie.org/1516691 - person farhan; 01.02.2011
comment
Я также должен добавить, что я пытаюсь записать с USB-микрофона. - person farhan; 01.02.2011