2015-08-26 18 views
0

Я беру аудиоданные из веб-камеры, используя VFW и аудиозапись Callback, и в то же время внутри тела одного и того же захвата обратного вызова направляет выбранные данные по умолчанию MAPPER, используя waveOutWrite.WaveOutWrite напрямую с обратного вызова аудиозахвата веб-камеры

Качество сигнала с веб-камеры составляет 1 канал/8 бит/11025 выборок в секунду. Формат звука поддерживается аудиоустройством по умолчанию, благодаря waveOpen с FORMAT_QUERY флаг.

Возвращение waveWriteOut является NOERROR, но то, что я могу услышать далеко от моих ожиданий. В комнате тихо, и это должно звучать как белый шум пустоты.

Pls, слушать звук YouTube rec

Она начинается, упаковка на упаковке размера с около 16K, структура WAVEHDR нормально. Затем он постепенно замедляется и выходит с неподтвержденной системой ошибкой.

Что это такое?

Ниже аудио ДТА ресивер код из VFW и lpWHdr приходит визуально Ok, даже внутренний флаг вызвал к 2 = Подготовленный .. похоже, VFW и WaveAudio созданы друг к другу :)

public static void capAudioStreamCallback(UIntPtr hWnd, ref WAVE.WAVEHDR lpWHdr) { 
    Say(String.Format(DateTime.Now.ToString("mm:ss:fff ") + "Received {0} of audio data", lpWHdr.dwBytesRecorded.ToString())); 
    Application.DoEvents(); 
    WA.WAVEHDR_FLAGS flag = (WA.WAVEHDR_FLAGS) lpWHdr.dwFlags; 
    if ((WA.WAVEHDR_FLAGS)lpWHdr.dwFlags != WA.WAVEHDR_FLAGS.WHDR_PREPARED) 
       CheckWAError("waveOutPrepareHeader", WA.waveOutPrepareHeader(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr))); 
    CheckWAError("waveOutWrite", WA.waveOutWrite(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr))); 
    CheckWAError("waveOutUnprepareHeader", WA.waveOutUnprepareHeader(phwo, lpWHdr, (uint)Marshal.SizeOf(lpWHdr))); 
    return; 
} 

    static void CheckWAError(string Func, WA.MMSYSERR err) { 
     if (err == WA.MMSYSERR.MMSYSERR_BASE_NOERROR) { Say(Func + " WA Ok"); return; } 
     IntPtr str = Marshal.AllocHGlobal(200); 
     string s = ""; 
     WA.waveOutGetErrorText(err, str, 200); 
     s = Marshal.PtrToStringAnsi(str); 
     Marshal.FreeHGlobal(str); 
     Say(Func + " err: " + s); 
    } 

I подумайте, что буфер не переполнен, потому что вы можете увидеть штамп в миллисекундах DateTime, и он гасит каждые 1400 миллисекунд и частоту выборки = 11025, а размер буфера составляет около 16500 байт = выглядит как Ok ..

UPD: Я просто скопировал неуправляемый буфер в управляемый и просмотрел его значения. Похоже на зубы пилы или даже на перегруженный синус. 0 4 0 3 0 32 109 213 255 251 255 243 241 97 0 7 0 2 1 1 0 5 0, а затем снова вверх и вниз примерно с одинаковыми номерами и тем же периодом. Не совсем, примерно то же (+/-). Кроме того, я могу записать сигнал с этой камеры с помощью внутреннего рекордера Windows, и я вижу, как уровень сигнала прыгает вверх и вниз по моему голосу вверх и вниз, так что микрофон веб-камеры также хорошо ... Я полагаю, что это может что-то не так с входным аудиосигналом VFW. Даже он принял WAVEFORMATEX и отправил обратно WAVEHDR, они оба в порядке ... но данные буфера заполнены каким-то другим источником, а не веб-камерой, хотя VFW говорит, что он должен быть с веб-камеры, потому что видео захватывает от того же источник, и он работает, я просто добавил один экземпляр: SendMessage (camHwnd, WM_CAP_SET_CALLBACK_WAVESTREAM, 0, audioCallback); Я очень уверен, что если я использую waveIn вместо VFW, он будет работать нормально .. Я проверю его позже .. Но почему VFW работает не так, как предполагалось?

+0

Возможно, это петля обратной связи. Кроме того, учитывая, что вы записываете из Интернета и подаете цифровой преобразователь, и оба они не обязательно работают с одинаковой скоростью, как вы знаете, что у вас нет переполнения буфера или underruns? – jaket

+0

Pls, см. дополнительный UPD –

ответ

0

Проблема была очень простой - это был отказ аппаратного обеспечения USB. Мне нужно было отключить USB-камеру и снова подключиться.

Но в любом случае я хотел бы поделиться своими знаниями об этом.

1) Мы должны использовать асинхронный механизм получения и отправки пакетов аудиоданных на конец воспроизведения. До тех пор, пока не будет воспроизведен первый буфер, мы должны избегать отправки нового буфера для воспроизведения. Метод называется «двойной» или даже «триплексной» буферизацией. И с VFW вы можете организовать его очень удобно, используя сообщение WM_CAP_GET_SEQUENCE_SETUP и структуру CAPTUREPARAMS. Параметр wNumAudioRequested используется для настройки количества различных буферов, которые будут циклически использоваться, для передачи аудиоданных в ваш аудиоконверт. По умолчанию установлено 10, что более чем достаточно.

2) Лучший способ проверить, является ли ваш звуковой сигнал действительным сигналом: в вашем WAVESTREAM Callback do Marshaling байтов из полученного буфера с аудиодатами в управляемый статический массив байтов. Затем, внутри обратного вызова, выполните вывод 50-100 значений образца с помощью Console.Write (array [i] + "") и посмотрите, изменяются ли значения в вашем голосе вверх и вниз. Учтите, что уровень Zero находится в середине значения WAVEFORMATEX-> wBitsPerSample, и в моем случае (8 бит/выборка) значения 125 126 127 128 129. Это принято как тишина и отсутствие сигнала, или нуль- шум. Как только вы уверены, что имеете правильные аудиоданные, теперь вы можете идти дальше к своей цели.

3) Помните, что когда вы работаете с микрофонным режимом, локальное устройство выходных волн лучше закрывать. Ваша цель - собирать аудиоданные для записи или отправки через Сеть. Не пытайтесь получить данные и waveOuit их локально. Иногда значение латентности вашего динамика немного выше скорости выборки данных микрофона, и вы будете беспорядочны с буферами, как это произошло со мной. Тогда я просто следовал принципу - «запись, когда вы собираете, сохранить или отправить аудиоданный, и он должен быть воспроизведен после записи или в то же время, но на конечный ПК

4) Продолжение. с кодом

 Смежные вопросы

  • Нет связанных вопросов^_^