Форум: "Media";
Текущий архив: 2008.03.02;
Скачать: [xml.tar.bz2];
ВнизwaveOut и waveIn одновременно Найти похожие ветки
← →
Sirus (2007-02-08 09:58) [0]Привет Мастерам...
Есть проблемка:
Подскажите как организовать сабж?
то есть нужно звук идущий из микрофона сразу же воспроизводить. (Сохранение записи в WAV и его воспроизведение не интересует)
← →
medved_68 © (2007-02-08 10:08) [1]
> то есть нужно звук идущий из микрофона сразу же воспроизводить.
>
Sirus Заполненый буфер (который тебе вернет драйвер зв.карты) сразу ставь в очередь на воспроизведение, а взамен него создавай новый или бери тот который вернется из очереди воспроизведения и ставь в очередь на запись. В принципе по сабжу: Есть исходник проги - пишет с микрофона в поток - по нажатию воспроизводит. Если подкорректировать то проблема снимется. :))))
← →
Сергей М. © (2007-02-08 10:10) [2]
> нужно звук идущий из микрофона сразу же воспроизводить
Если аудиоподсистема не поддерживает fullduplex-режим, то не получится.
← →
Sirus (2007-02-08 10:23) [3]Читал в доках что одновременно открыть устройства на запись и воспроизведение не получится.
Я попытался сделать так:
Открываю запись
получаю буфер записи
закрываю запись и открываю вопроизведение
отправляю полученный буфер на воспроизведение
закрываю воспроизведение
И ни черта не получается :( ничего не слышно
> Есть исходник проги - пишет с микрофона в поток - по нажатию воспроизводит. Если подкорректировать то проблема снимется. :))))
Был бы очень признателен за исходник
И как узнать поддерживается ли на компе полный дуплекс?
← →
medved_68 © (2007-02-08 10:49) [4]
> И как узнать поддерживается ли на компе полный дуплекс?
Открыть устройство на запись проанализировать открытие на предмет ошибки, сделать попытку открыть устройство на воспроизведение если функция вернет ИД устройства - сделвть вывод о поддержке, если нет (ошибка открытия устройства) .....на нет и суда нет :)))
← →
medved_68 © (2007-02-08 10:50) [5]
> отправляю полученный буфер на воспроизведение
А как отправляешь???
← →
TRUNK © (2007-02-08 10:57) [6]
> Sirus (08.02.07 09:58)
Если "нужно звук идущий из микрофона сразу же воспроизводить", то связываться с waveOut и waveIn имеет смысл, только если нужно производить обработку звука в реальном времени ("почти реальном" - задержка будет в любом случае).
Тут нужно ещё решить сложную проблему синхронизации. Наилучший вариант, когда и запись, и воспроизведение синхронизируются одним и тем же источником, т.е. используется одна звуковая карта и на вход, и на выход. Делал я как-то программу, которая в "почти реальном" времени меняет АЧХ - больше половины времени потратил на подгонку синхронизации.
← →
Плохиш © (2007-02-08 11:18) [7]
> Sirus (08.02.07 09:58)
> то есть нужно звук идущий из микрофона сразу же воспроизводить.
Хм, я конечно понимаю, что сайт по делфи и всё такое, но у меня и без сторонних программ всё так и работает. Может стоит, для начала, "Регулятор громкости" запустить и посмотреть, чем же там порегулировать можно?
← →
Sirus (2007-02-08 11:55) [8]
>> отправляю полученный буфер на воспроизведение
> А как отправляешь???
MM_WIM_DATA: begin
Hdr:=PWaveHdr(msg.LParam);
WaveInStop(WaveIn^);
if WaveIn<>nil then WaveInReset(WaveIn^);
if WaveIn<>nil then WaveInClose(WaveIn^);
Dispose(WaveIn);
WaveOut:=new(PHWaveOut);
WaveOutOpen(WaveOut,0,@WaveFormat,handle,0,CALLBACK_WINDOW);
WaveOutPrepareHeader(WaveOut^,Hdr,sizeOf(TWaveHdr));
WaveOutWrite(WaveOut^,Hdr,Sizeof(TWaveHdr));
end;
> Хм, я конечно понимаю, что сайт по делфи и всё такое, но у меня и без
> сторонних программ всё так и работает. Может стоит, для начала,
> "Регулятор громкости" запустить и посмотреть, чем же там порегулировать
> можно?
Меня такой вариант не устраивает, не хочу бегать по пользователям и каждому включать микрофон в параметрах громкости Windows
← →
Sirus (2007-02-08 12:02) [9]Вот весь код. Он не работает.
Подскажите что неправильно и как его исправить.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MMSystem, ShellAPI;
type
TArrayBuf = array[0..1023]of byte;
PArrayBuf = ^TArrayBuf;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
WaveFormat:TWaveFormatEx;
WaveIn:PHWaveIn;
WaveOut:PHWaveOut;
IsOn:boolean;
procedure WNDPROC(var msg:TMessage); override;
procedure InitWave(r: boolean);
end;
var
Form1: TForm1;
ci, co: integer;
implementation
{$R *.dfm}
Procedure TForm1.WNDPROC(var msg:TMessage);
var Hdr: PWaveHdr;
WaveBuf: PArrayBuf;
i: integeR;
begin
INHERITED;
case msg.Msg of
MM_WIM_OPEN: begin
//Открытие записи
end;
MM_WIM_CLOSE: begin
//Закрытие записи
end;
MM_WIM_DATA: begin
ci:=ci+1;
label1.Caption:=IntTostr(ci);
Hdr:=PWaveHdr(msg.LParam);
WaveInStop(WaveIn^);
if WaveIn<>nil then WaveInReset(WaveIn^);
if WaveIn<>nil then WaveInClose(WaveIn^);
Dispose(WaveIn);
WaveOut:=new(PHWaveOut);
WaveOutOpen(WaveOut,0,@WaveFormat,handle,0,CALLBACK_WINDOW);
WaveOutPrepareHeader(WaveOut^,Hdr,sizeOf(TWaveHdr));
WaveOutWrite(WaveOut^,Hdr,Sizeof(TWaveHdr));
end;
MM_WOM_DONE: begin
co:=co+1;
label2.Caption:=IntTostr(co);
WaveOutClose(WaveOut^);
Dispose(WaveOut);
if IsOn=False Then Exit;
WaveIn:=new(PHWaveIn);
WaveInOpen(WaveIn,0,@WaveFormat,handle,0,CALLBACK_WINDOW);
WaveBuf:=new(PArrayBuf);
Hdr:=new(PWaveHdr);
with Hdr^ do begin
lpData:=pointer(WaveBuf);
dwBufferLength:=sizeof(WaveBuf);
dwBytesRecorded:=0;
dwUser:=0;
dwFlags:=0;
dwLoops:=0;
end;
WaveInPrepareHeader(WaveIn^,Hdr,sizeOf(TWaveHdr));
WaveInAddBuffer(WaveIn^,Hdr,Sizeof(TWaveHdr));
WaveInStart(WaveIn^);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Initwave(True);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Initwave(False);
end;
procedure TForm1.InitWave(r: boolean);
var WaveHdr: PWaveHdr;
WaveBuf: PArrayBuf;
i: integer;
begin
ci:=0;
co:=0;
if r then begin
IsOn:=True;
WaveFormat.wFormatTag:=WAVE_FORMAT_PCM;
WaveFormat.nChannels:=1;
WaveFormat.nSamplesPerSec:=44100;
WaveFormat.nAvgBytesPerSec:=44100;
WaveFormat.nBlockAlign:=4;
WaveFormat.wBitsPerSample:=8;
WaveIn:=new(PHWaveIn);
WaveInOpen(WaveIn,0,@WaveFormat,handle,0,CALLBACK_WINDOW);
WaveBuf:=new(PArrayBuf);
WaveHdr:=new(PWaveHdr);
with WaveHdr^ do begin
lpData:=pointer(WaveBuf);
dwBufferLength:=sizeof(WaveBuf);
dwBytesRecorded:=0;
dwUser:=0;
dwFlags:=0;
dwLoops:=0;
end;
WaveInPrepareHeader(WaveIn^,WaveHdr,sizeOf(TWaveHdr));
WaveInAddBuffer(WaveIn^,WaveHdr,Sizeof(TWaveHdr));
WaveInStart(WaveIn^);
end else begin
IsOn:=False;
WaveInStop(WaveIn^);
if WaveIn<>nil then WaveInReset(WaveIn^);
if WaveIn<>nil then WaveInClose(WaveIn^);
Dispose(WaveIn);
end;
end;
end.
← →
TRUNK © (2007-02-08 12:40) [10]Для описанных целей способ работы через сообщения не годится,
особенно учитывая размер буфера.
P.S. А с какой радости WaveFormat.nBlockAlign = 4, если он равен 1?
P.P.S.nBlockAlign := nChannels*(wBitsPerSample div 8)
← →
Sirus (2007-02-08 12:48) [11]> Для описанных целей способ работы через сообщения не годится,
> особенно учитывая размер буфера.
подскажи способ который сгодится.
> P.P.S. nBlockAlign := nChannels*(wBitsPerSample div 8)
Спасибо
← →
TRUNK © (2007-02-08 13:05) [12]Для того чтобы быстро узнать о завершении обработки буфера, нужно использовать так называемый polling, т.е. постоянный опрос состояния флага WHDR_DONE в TWaveHdr.dwFlags. Для этого я делал отдельный поток, который и занимался всем процессом по записи и/или воспроизведению звука.
← →
Плохиш © (2007-02-08 13:41) [13]
> Меня такой вариант не устраивает, не хочу бегать по пользователям
> и каждому включать микрофон в параметрах громкости Windows
http://narod.yandex.ru/cgi-bin/yandmarkup?cluster=14&prog=0x2757571A&HndlQuery=418343216&PageNum=0&g=3&d=0&q0=4 22254800&p=
← →
medved_68 © (2007-02-08 13:41) [14]
> MM_WIM_DATA: begin
> Hdr:=PWaveHdr(msg.LParam);
> WaveInStop(WaveIn^);
> if WaveIn<>nil then WaveInReset(WaveIn^);
> if WaveIn<>nil then WaveInClose(WaveIn^);
Dispose(WaveIn);
WaveOut:=new(PHWaveOut);
> WaveOutOpen(WaveOut,0,@WaveFormat,handle,0,CALLBACK_WINDOW);
>
> WaveOutPrepareHeader(WaveOut^,Hdr,sizeOf(TWaveHdr));
>
> WaveOutWrite(WaveOut^,Hdr,Sizeof(TWaveHdr));
> end;
Sirus ну и что же ты хотел услышать???? Ведь ты собственноручно убиваешь буфер с звуковыми данными и создаешь новый который ставишь в очередь на воспроизведение мда уж.....комментарии излишни :)))
← →
Sirus (2007-02-09 05:45) [15]Я думал буфер остается в переменной Hdr
← →
Vovan # 2 (2007-02-09 08:54) [16]Никаких выделений памяти при MM_WIM_DATA, только сразу другой подставить буфер.
← →
medved_68 © (2007-02-09 13:39) [17]
> Я думал буфер остается в переменной Hdr
:))) Остается, но не буфер а указатель на него (Hdr:=PWaveHdr). А после Dispose указатель фактически указывает на недоступную область памяти. Поэтому если хочешь работать так, то сначала выдели новую память, перелей туда звуковые данные, и только потом освобождай то что пришло от драйвера. :))
← →
Alter Ego (2007-03-28 16:57) [18]
> Если "нужно звук идущий из микрофона сразу же воспроизводить",
> то связываться с waveOut и waveIn имеет смысл, только если
> нужно производить обработку звука в реальном времени ("почти
> реальном" - задержка будет в любом случае).
>
Поподробнее пожалуйста.
Я хочу цеплять DSP эфекты (библиотека BASS_FX) на входящий из микрофона сигнал (типа електрогитарная примочка).
← →
Сергей М. © (2007-03-28 17:09) [19]
> Alter Ego (28.03.07 16:57) [18]
> типа електрогитарная примочка
"Типа електрогитарные примочки" при посредстве BASS сойдут разве что для программных экспериментов.
Серьезные же "типа електрогитарные примочки" реализуются при посредстве ASIO, ALSA, к коим BASS не имеет ни малейшего отношения, поскольку попросту не использует эти технологии и интерфейсы.
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2008.03.02;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.048 c