Как определить уровень сигнала на входе звуковой карты?
От: Allock  
Дата: 16.03.04 13:33
Оценка:
Добрый день!

У меня в настоящее время стоит задача слушать вход звуковой карты. Если уровень сигнала превысит некоторое значение — начинать запись. Если окажется ниже — останавливать.

Объект для записи в формате PCM я написал.
Теперь мне нужно в сжатые сроки реализовать определение уровеня входного сигнала (чтобы опрашивать его по таймеру).

Буду Вам признателен за содействие.

С уважением.
Aleks Allock
Re: Как определить уровень сигнала на входе звуковой карты?
От: Dimonka Верблюд  
Дата: 16.03.04 14:05
Оценка:
Здравствуйте, Allock, Вы писали:

A>Добрый день!


A>У меня в настоящее время стоит задача слушать вход звуковой карты. Если уровень сигнала превысит некоторое значение — начинать запись. Если окажется ниже — останавливать.


A>Объект для записи в формате PCM я написал.

A>Теперь мне нужно в сжатые сроки реализовать определение уровеня входного сигнала (чтобы опрашивать его по таймеру).

A>Буду Вам признателен за содействие.


A>С уважением.

A>Aleks Allock

tut:
http://rsdn.ru/Forum/Message.aspx?mid=519121#519121
Автор: crazzypolman
Дата: 26.01.04
Re[2]: Как определить уровень сигнала на входе звуковой карт
От: Allock  
Дата: 16.03.04 15:35
Оценка:
Здравствуйте, Dimonka, Вы писали:

D>tut:

D>http://rsdn.ru/Forum/Message.aspx?mid=519121#519121
Автор: crazzypolman
Дата: 26.01.04


Это сильно.
Я написал объект, который не завязан на MCI напрямую, поэтому с waveIn не разбирался...

Пробовал через mixerGetControlDetails, но выдает ошибку с кодом 11 (неправильный параметр...)

С уважением.
Re[3]: Как определить уровень сигнала на входе звуковой карт
От: Dimonka Верблюд  
Дата: 16.03.04 15:58
Оценка:
Здравствуйте, Allock, Вы писали:

A>Я написал объект, который не завязан на MCI напрямую, поэтому с waveIn не разбирался...


Ну я пока не слышал о методах, позволяющих узнать громкость звука, не просмотрев его составляющие семплы.
Да и вроде в API таких функций пока не придумали. Так что придётся звук записывать. Причём, если не так важна точность, то можно делать это с очень низкой дискретизацией. Если важен сам факт наличия звука, то и записывать звук можно не постоянно, а, например, раз в секунду.
Re[4]: Как определить уровень сигнала на входе звуковой карт
От: Аноним  
Дата: 17.03.04 04:30
Оценка:
Я взят TMediaPlayer.
Обернул его, сделал для Create параметром формат файла (например PCM-22кГц-8бит), создаю временный пустой файл в этом формате, беру его МедиаПлэйером, начинаю писать, в конце записи меняю имя файла на нужное, сохраняю... Все.
Предельно упрощенно.

Но раньше от меня требовалось быстренько дать только 4 функции (Record, Pause, Resume, Stop). Их вызывали снаружи внешней проограммой.
Теперь решили внедрить все в мой объект (как бы диктофон из него сделать).
Теперь мне нужно при Create, начинать слушать Line in карты и заканчивать при Free.

Я пробовал миксер. Не получилось.
Пробовал взять TMediaPlayer.deviceID и посмотреть на него, как в МСДН рекомендуют:
        flags := (MCI_WAIT OR MCI_STATUS_ITEM);
        mciStatus.dwCallback := 0;
        mciStatus.dwTrack := 0;
        mciStatus.dwItem := MCI_WAVE_STATUS_LEVEL;
        mciResult := MciSendCommand(mpRecorder.deviceID, MCI_STATUS, flags, DWORD(@mciStatus));
        ShowMessage(IntToStr(mciStatus.dwReturn));

Выдает постоянное неизменяющееся значение.

Видемо я где-то что-то явно не понимаю и не так делаю.

Блин.
А я пока не сдвинулся... Мне тут уже и DirectX рекомендовали (DirectShow — IAMCrossBar)

С уважением и признательностью за ответы.
Allock
Re: А если waveIn???
От: Allock  
Дата: 17.03.04 17:51
Оценка:
Нашел действующий примерчик.
На его основе сейчас пробую вот так:

procedure TfrmMain.Button3Click(Sender: TObject);
type
    TMemBlock = array[0..100000] of byte; //буфер данных
var
    rc: MMResult;
    waveFormat: PPCMwaveFormat;
    dMemBlock: TMemBlock;
    header: TWaveHdr;
    hWaveIn: PHWaveIn;
begin
    if (WaveInGetNumDevs = 0) then
        messagebox(0,'Error', 'нет звуковой платы', 0);

    waveFormat := New(PPCMwaveFormat);
    with waveFormat^.wf do begin
        WFormatTag := WAVE_FORMAT_PCM; {PCM format}
        NChannels := 2; {mono1 stereo2}
        NSamplesPerSec := 44100; {11kHz sampling}
        NAvgBytesPerSec := 176400; {we aim to use 8 bit sound so only 11k per second}
        NBlockAlign := 4; {only one byte in each sample}
        waveformat^.wBitsPerSample := 16; {8 bits in each sample}
    end;

// Если написать (header) то не работает!!!
    with header do begin
        lpdata := @dMemBlock; // pointer(memBlock);
        dwbytesrecorded := 40000;
        dwbufferlength := 40000;
        dwUser := 0;
        dwflags := 0;
        dwloops := 0;
    end;

//выделить память
    hWaveIn := New(PHWaveIn);

//открыть зв.карту, определяем Callback функцию формы Form2
    rc := waveInOpen(hWaveIn, WAVE_MAPPER, @waveformat^.wf, 0, 0, 0);
    if (rc <> 0) then
        messagebox(0,'Error', 'не открывается waveIn', 0);

//готовим буфер звук.карты
    rc := waveInPrepareHeader(hWaveIn^, @header, sizeof(TWaveHdr));
    if (rc <> 0) then
        messagebox(0, 'waveInPrepareHeader - Out Prepare error', 'error', 0);

// передаем данные в буфер
    rc := waveInAddBuffer(hWaveIn^, @header, sizeof(TWaveHdr));
    if (rc <> 0) then
        messagebox(0, 'waveInAddBuffer error', 'error', 0);

// освобождаем буфер звук.карты
// !!!! ЗДЕСЬ ОШИБКА 33
    rc := waveInUnprepareHeader(hWaveIn^, @header, sizeof(TWaveHdr));
    if (rc <> 0) then
        messagebox(0, 'waveInUnprepareHeader error: ' + IntToStr(rc), 'error', 0);

// включаем запись
    i:=waveInStart(HWaveIn^);
    if i<>0 then
      messagebox(0,'Wave out error','error',0);


Теперь, по идее в dMemBlock лежат данные.
Получается здоровенный буфер.
А как из этого буфера вынуть мнгновенное значение уровня сигнала?

С уважением.
Allock
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.