Конференция "Media" » Как без заиканий проиграть звук с микрофона! [D6, Win95/98, Win2k, WinXP]
 
  • __Unknown__ (20.07.07 10:18) [0]
    С микрофона!!

    WaveInStart(WaveDev);
    While Not Terminated Do
       Begin
         Res:=WaitForSingleObject(Event,INFINITE);
         Case Res of
           WAIT_OBJECT_0:
                         Begin
                            If BufHead.dwFlags and WHDR_DONE<>0 Then
                              Begin
                                Synchronize(OnBufferEvent);
                              End;
                            Err:=WaveInAddBuffer(WaveDev,@BufHead,SizeOf(BufHead));
                            If Err<>0 Then;
                          End;

         End;

    Воиспроизведение:

    Flag:=True;

     While Not Terminated Do
       Begin
         If (BufHead.dwFlags and WHDR_DONE<>0)or(Flag) Then
           Begin
             If AddBuffer Then
               Begin
                 WaveOutWrite(WaveDev,@BufHead,SizeOf(BufHead));
                 Flag:=False;
               End;
           End;
         Res:=WaitForSingleObject(Event,100);
         Case Res of
           WAIT_OBJECT_0:
              Begin
                 If BufHead.dwFlags and WHDR_DONE<>0 Then
                  Begin
                     Flag:=True;
                  End;
               End;
         End;
       End;

    Если я при получении буфера отсылаю его на воиспроизведение в другой поток то он воспроизводится но с небольшими заиканиями! И через время нарастает задержка между сказанным и воиспроизведенным бывает до 15сек!
    У кого есть пример как воиспроизвести правильно звук
  • Dib@zol © (20.07.07 10:35) [1]
    Мож использовать как в ОГЛ/ДХ графике двойную буферизацию? Пишется напр только полученный звук в буфер, в то время как из другого воспроизводится предыдущий. Затем "передний" и "задний" буфера переключаются.
  • __Unknown__ (20.07.07 10:43) [2]
    Не получится! У меня звук одновременно отображается в Synchronize();
    Т.е. хочеш сказать, что у меня рабочий пример и ошибок и коментарий по коду нет?
  • Dib@zol © (20.07.07 10:49) [3]
    Вообче ещё не пробовал... Микрофон кудато засовал и забыл куда :) Если найду - протестю, отпишуся.
  • Сергей М. © (20.07.07 10:54) [4]

    > __Unknown__   (20.07.07 10:43) [2]



    > Не получится


    Ну тогда и избавиться от "заиканий" не получится.

    Рецепт тебе был дан верный:

    1. Использовать мультибуферизацию ввода.
    2. Отказаться от Synchronize()
  • Сергей М. © (20.07.07 11:26) [5]

    > __Unknown__


    И вообще - не мучайся, возьми готовый фриварный компонент с http://www.droopyeyes.com

    Хоть в кач-ве "черного ящика", хоть для изучения как это делается (исходники доступны).
  • __Unknown__ (21.07.07 00:40) [6]
    Переделал так!
    hBuf:=GlobalAlloc(GMEM_MOVEABLE and GMEM_SHARE,hBufSize shl 1);
     BufAddr:=GlobalLock(hBuf);
     BufAddrArr[0]:=BufAddr;
     BufAddrArr[1]:=Pointer(Integer(BufAddr)+hBufSize);
     //-----
     FBufIndex:=0;
     BufHead[0].lpData:=BufAddrArr[0];
     BufHead[0].dwBufferLength:=hBufSize;
     BufHead[0].dwFlags:=WHDR_BEGINLOOP;
     BufHead[1].lpData:=BufAddrArr[1];
     BufHead[1].dwBufferLength:=hBufSize;
     BufHead[1].dwFlags:=WHDR_BEGINLOOP;
     //-----
     WaveInPrepareHeader(WaveDev,@BufHead[0],SizeOf(TWAVEHDR));
     WaveInPrepareHeader(WaveDev,@BufHead[1],SizeOf(TWAVEHDR));
     WaveInAddBuffer(WaveDev,@BufHead[FBufIndex],SizeOf(TWAVEHDR));
     WaveInStart(WaveDev);
     While Not Terminated Do
       Begin
         Res:=WaitForSingleObject(Event,INFINITE);
         Case Res of
           WAIT_OBJECT_0: Begin
                            FOldIndex:=FBufIndex;
                            FBufIndex:=FBufIndex Xor 1;
                            WaveInAddBuffer(WaveDev,@BufHead[FBufIndex],SizeOf(TWAVEHDR));
                            If (BufHead[FOldIndex].dwFlags and WHDR_DONE)=WHDR_DONE Then
                              Begin
                                OnBufferEvent;
                              End;
                            End;

         End;

       End;
     WaveInReset(WaveDev);
     WaveInUnPrepareHeader(WaveDev, addr(BufHead[0]), sizeof(TWAVEHDR));
     WaveInUnPrepareHeader(WaveDev, addr(BufHead[1]), sizeof(TWAVEHDR));
     WaveInClose(WaveDev);
     GlobalUnlock(hBuf);
     GlobalFree(hBuf);
     CloseHandle(Event);

    Короче до процедуры OnBufferEvent не доходит!
    Если убрать проверку флагов, то перед началом воспроизведения стоит свист 1 секунду!

    Я пытался передать звук по сети и происходит следующее:
    Каждый раз увеличивается задержка между сказанным мной и полученным по сети.
    Может кто подскажет в чем баг?
    Размер буфера для каждой настройки расчитывается по формуле
    BufSize:=(SamplesPerSec shr 2)*(BitsPerSample shr 3);
    Т.е. вне зависимо от качества снимаемого звука задержка на его заполнение (по моему мнению :) ) должна быть одинаковой (1/4 секунды)!
    И вне зависимости от выборки (4000Нz или 44100Нz) звук начинает запаздывать привоспроизведении.
  • __Unknown__ (21.07.07 00:42) [7]
    Тоже самое наблюдается при локальной обработке, т.е. считал воспроизвел...
    Не знаю что делать :(
    :)
  • Сергей М. © (23.07.07 08:23) [8]

    > Не знаю что делать


    Я ж тебе не зря ссылку на компоненты привел.

    Что мешает посмотреть в исх-ках заведомо корректно работающего компонента как это делается правильно ?
  • Sdubaruhnul (23.07.07 15:23) [9]
    >Сергей М. ©   (23.07.07 08:23) [8]

    Так ведь там чувак спрашивал про пример Генератора с Королевства Делфи, а ты сказал, что там неправильная система.
  • Сергей М. © (23.07.07 15:49) [10]

    > Sdubaruhnul   (23.07.07 15:23) [9]


    > Так ведь там чувак


    "там" это где ?

    Речь сейчас идет о "здесь")
  • medved_68 © (23.07.07 16:17) [11]

    > Тоже самое наблюдается при локальной обработке, т.е. считал
    > воспроизвел...
    > Не знаю что делать :(
    > :)

    Локальная - это как??? Куда то считал буфер, сохранил в памяти и воспроизвел???
  • Alive (18.03.08 12:33) [12]
    курить синхронизацию процессов!
    pulseEvent!!
    считал - записал - пульсанул... <- в одном потоке
    подождал события - воспроизвел <- в другом потоке
    и каждый поток в цикле.
 
Конференция "Media" » Как без заиканий проиграть звук с микрофона! [D6, Win95/98, Win2k, WinXP]
Есть новые Нет новых   [134431   +15][b:0][p:0.001]