Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
8-1174354813
DDDeN
2007-03-20 04:40
2008.03.02
Передать аудио-поток на IceCast


15-1201524459
DillerXX
2008-01-28 15:47
2008.03.02
MatAn music


15-1201444871
Черный Шаман
2008-01-27 17:41
2008.03.02
Delphi типы исключений.


15-1201363081
Константинов
2008-01-26 18:58
2008.03.02
Помогите с аской 5.1 человек ждет,


15-1200865288
DillerXX
2008-01-21 00:41
2008.03.02
На материнке есть маркировка с названием модели?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский