Мне надо на выходе аудиокарты получить сигнал синусоидильной формы. При передаче блоков данных, мезду ними образуется пауза. Как эту паузу сделать минимальной?
Вот мой код: ..... hEvent:=CreateEvent(nil,false,false,nil); fmt.wFormatTag:=WAVE_FORMAT_PCM; fmt.nChannels:=1; fmt.nSamplesPerSec:=df; fmt.nAvgBytesPerSec:=df; fmt.nBlockAlign:=1; fmt.wBitsPerSample:=8; fmt.cbSize:=0; waveOutOpen( @hSound,0,@fmt,hEvent,0,CALLBACK_EVENT); p:=pData; for i:=0 to dF*MaxTimer-1 do begin p^:=128+Floor(A*sin(2*pi*Hz/df*i)); inc(p); end; .... pHeader.lpData:=pData; pHeader.dwBufferLength:=MaxTimer*df; pHeader.dwFlags := 0; pHeader.dwLoops := 0; pHeader.dwBytesRecorded:=0; pHeader.lpNext:=nil; waveOutPrepareHeader( hSound, pHeader,sizeof(WAVEHDR)); //первый блок данных ResetEvent(hEvent); waveOutWrite(hSound, pHeader,sizeof(WAVEHDR) ); WaitForSingleObject(hEvent,Infinite); //второй блок данных ResetEvent(hEvent); waveOutWrite(hSound, pHeader,sizeof(WAVEHDR) ); WaitForSingleObject(hEvent,Infinite);
А вообще есть возможность избавиться от паузы в пользоваетильском режиме? Или придётся взаимодействовать напрямую с дровами?
Кто-нибудь знает как поставить выходные буфферы в очередь? для этого надо правиль сконфигурировать в структуре WAVEHDR параметры dwFlags и dwLoops если я правильно понимяю?!
вообще такую программу встечал готовую и кажется с исходниками... только вот где?...( А что если событие твое с большим приоритетом сделать? Ведь паузы - ввиду переключения задач винда дает скорее всего. Т.е. ты real-time хочешь сделать там где его нет, значит надо заствить ее НЕ прерываться на...
Может я чего не понял? Но у МС есть либа такая ДиректСаунд начиная с самых первых директХ. СДК поставляется с доками и примерами, немного перелепив какой попроще вы получите то, что хотели.
Задержка там восновном из-за переписывания данных из буфера в буфер, смешивания, проталкивания по стеку драйверов вниз. Еще один момент, я себе плохо представляю вклад в неаккуратность сигнала, но наверно еще стоит согласовывать конец и начало синусоиды, чтобы не было скачка фазы во время подачи нового буфера.
все проблему решил. Надо просто сформировать очередь буферов. .... fmt.wFormatTag:=WAVE_FORMAT_PCM; fmt.nChannels:=1; fmt.nSamplesPerSec:=df; fmt.nAvgBytesPerSec:=dF; fmt.nBlockAlign:=1; fmt.wBitsPerSample:=8; fmt.cbSize:=0; waveOutOpen(@hSound,WAVE_MAPPER,@fmt,Form1.Handle,0,CALLBACK_WINDOW); //первый буффер Header1.lpData:=pData1; Header1.dwBufferLength:=BufSize; Header1.dwFlags:=WHDR_BEGINLOOP; //флаг начала Header1.dwLoops:=0; waveOutPrepareHeader(hSound,@Header1,SIZEof(Header1)); waveOutWrite(hSound,@Header1,sizeof(Header1)); //второй буффер Header2.lpData:=pData2; Header2.dwBufferLength:=BufSize; Header2.dwFlags:=WHDR_DONE; // флаг продолжения Header2.dwLoops:=0; waveOutPrepareHeader(hSound,@Header2,SIZEof(Header2)); waveOutWrite(hSound,@Header2,sizeof(Header2)); и добавляю вновь и вновь с помощью обработчика события .... procedure TForm1.MyProc; begin // ShowMessage('Yes'); if f then begin f:=false; waveOutUnprepareHeader(hSound,@Header1,sizeof(Header1)); Header1.lpData:=pData1; Header1.dwBufferLength:=BufSize; Header1.dwFlags:=WHDR_DONE; Header1.dwLoops:=0; waveOutPrepareHeader(hSound,@Header1,SIZEof(Header1)); waveOutWrite(hSound,@Header1,sizeof(Header1)); end else begin f:=true; waveOutUnprepareHeader(hSound,@Header2,sizeof(Header2)); Header2.lpData:=pData2; Header2.dwBufferLength:=BufSize; Header2.dwFlags:=WHDR_DONE; Header2.dwLoops:=0; waveOutPrepareHeader(hSound,@Header2,SIZEof(Header2)); waveOutWrite(hSound,@Header2,sizeof(Header2)); end; end; И ни какой паузы
Нет. Читайте доку на дирСнд. Впрочем.. С директСоундом дело давно не имел. Потому только шаблон. Дальше книжки, дока, сорцы, эксперименты. - получаем первичный звуковой буфер. - на каждый отдельный звук выделяем по вторичному буферу. - пишем во вторичный буффер выборки. - создаем событие по которому дописывать будете - запускаем на выполнение, указав событие и указав, чтоб вызывало, когда проиграет пол-буфера - ждем событие - узнаем какая половина буфера освободилась. Блокируем и переписываем ее. Разблокируем. Если быстродействия не хватит (скажем 486 + сложные вычисления/перерисовки), пускаем в отдельном потоке. ЗЫ возможно я что-то напутал. Загляните в доку.