Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.01.2014, 18:31   #1
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
Сообщение Запись WAVE потока из COM порта

Погите плиз как правильно писать данные с COM порта GSM модема:
Код:
...где то там ATA...ну а потом
AudioPort.ClearBuffer(True, True);
  MSec := GetTickCount + 10;
  repeat
        FillChar(Buf, 320, 0);
        AudioPort.Read(Buf, 320);
        Buffer := Buffer + Buf;
        Sleep(20);
  until MSec < GetTickCount;

  DataHeader.idData  := 'data';
  DataHeader.DataLen := Length(ReadBuffer);

  WaveHeader.idRiff      := 'RIFF';
  WaveHeader.RiffLen     := DataHeader.DataLen - 8;
  WaveHeader.idWave      := 'WAVE';
  WaveHeader.idFmt       := 'fmt ';
  WaveHeader.InfoLen     := 16;
  WaveHeader.WaveType    := 1;
  WaveHeader.Ch          := 1;
  WaveHeader.Freq        := 8000;
  WaveHeader.BytesPerSec := 16000;
  WaveHeader.Align       := 2;
  WaveHeader.Bits        := 16;

  F.WriteBuffer(WaveHeader, SizeOf(TWaveHeader));
  F.WriteBuffer(DataHeader, SizeOf(TDataHeader));
  F.WriteBuffer(ReadBuffer[1], Length(ReadBuffer)*SizeOf(Char));
  SetString(ReadBuffer, PChar(F.Memory), F.Size);
  F.SaveToFile(sAppPath + 'voice\1.wav');
  F.Free;
WAVE файл воспроизводится AIMпом, но sndrec32.exe - его не воспринимает. И может быть альгорим лучше предложите?
qZED вне форума Ответить с цитированием
Старый 22.01.2014, 19:36   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

...скорее беда в заголовке файла, в описании структуры WAV PCM.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 10.02.2014, 19:16   #3
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
По умолчанию

Это опять я...
Звук из com порта(USB модем) считывается
repeat
ReadData := AudioPort.Read(Buf, 320);
F.WriteBuffer(Buf, ReadData);
until CallFinished = True;
TxAndWait('AT+CHUP');

но он очень тихий...можно как то увеличить звук PCM файла?
qZED вне форума Ответить с цитированием
Старый 10.02.2014, 23:13   #4
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Можно. Просто умножайте каждый полученный отсчет на заданный коэффициент. Также следует учитывать возможность ограничения сигнала.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 10.02.2014, 23:53   #5
blackstrip
Форумчанин
 
Аватар для blackstrip
 
Регистрация: 21.01.2012
Сообщений: 240
По умолчанию

Беглым взглядом по коду:
Код:
WaveHeader.RiffLen := DataHeader.DataLen - 8;
неправильно, т.к. здесь нужно указать размер всего wav файла минус 8 байт (которые составляют 'RIFF'+4байта поля RiffLen), а не размер данных data-чанка минус 8 байт.

Правильней будет (размер заголовка data-чанка + размер данных + размер заголовка fmt-чанка + размер данных fmt чанка):

Код:
WaveHeader.RiffLen := 8 + DataHeader.DataLen + 8 + 16
А так вроде все правильно, если в WaveHeader-типе все поля нужного размера в байтах, а именно:
4 байта WaveHeader.idRiff := 'RIFF';
4 байта WaveHeader.RiffLen := DataHeader.DataLen - 8;
4 байта WaveHeader.idWave := 'WAVE';
4 байта WaveHeader.idFmt := 'fmt ';
4 байта WaveHeader.InfoLen := 16;
2 байта WaveHeader.WaveType := 1;
2 байта WaveHeader.Ch := 1;
4 байта WaveHeader.Freq := 8000;
4 байта WaveHeader.BytesPerSec := 16000;
2 байта WaveHeader.Align := 2;
2 байта WaveHeader.Bits := 16;

Последний раз редактировалось blackstrip; 10.02.2014 в 23:57.
blackstrip вне форума Ответить с цитированием
Старый 11.02.2014, 00:01   #6
blackstrip
Форумчанин
 
Аватар для blackstrip
 
Регистрация: 21.01.2012
Сообщений: 240
По умолчанию

Цитата:
Сообщение от raxp Посмотреть сообщение
Можно. Просто умножайте каждый полученный отсчет на заданный коэффициент. Также следует учитывать возможность ограничения сигнала.
Только надо учесть, что в 8-битном файле все значения записываются относительно $80, которое является нулем. Т.е. $00 - это "-128", а $FF - это "127".

А если 16-битный WAV-файл записывать, то там уже нулем является $0000 как положено, и можно умножать действительно на коэффициент.

А еще лучше имхо для 16-битных, например, использовать массив integer-ов, который перед записью поэлементно рубить до границ от -32768 до 32767, и потом превращать в smallint (двухбайтовые со знаком).

P.s. кстати, автор темы, а у вас в вашем потоке точно 16-битный звук идет? Если идет 8-битный, а вы его записываете в 16-битный файл, то у вас получается громкость около 1/256-той от максимальной. Отсюда так тихо. Либо пишите в 8-битный wav, прибавляя к каждому отсчету $80 перед записью. Либо домножьте каждый отсчет вашего звука на $FF (чтоб сделать его максимально громким).

p.p.s хотя конечно, если б шел 8-битный, а вы записывали бы его как 16-битный, то все бы сбилось совсем, по два реальных 8-битных отсчета записывались бы в файл как один 16-битный, а скорость воспроизведения такого потока стала бы в 2 раза больше, т.к. за один раз вместо 8-битного отсчета проигрывался бы сразу 16-битный отсчет скомканный из реальных двух 8-битных.

Последний раз редактировалось blackstrip; 11.02.2014 в 00:21.
blackstrip вне форума Ответить с цитированием
Старый 11.02.2014, 18:02   #7
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
По умолчанию

Громкость увеличил.
Но вот другой косячок:
repeat
ReadData := AudioPort.Read(Buf, 320);
F.WriteBuffer(Buf, ReadData);
until CallFinished = True;

На телефоне показывает что 5 секунд длился разговор, а записалось только 2. Такое подозрение что после входящей команды - "положили трубку", голосовые данные еще содержаться в AudioPort.
qZED вне форума Ответить с цитированием
Старый 11.02.2014, 18:14   #8
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
По умолчанию

А извиняюсь...заголовок WAVE то я не подправил...
Спасибо товарищи!
+ по поводу заголовка потом еще спрошу...

Последний раз редактировалось qZED; 11.02.2014 в 19:11.
qZED вне форума Ответить с цитированием
Старый 04.03.2014, 17:29   #9
qZED
Пользователь
 
Регистрация: 13.05.2009
Сообщений: 26
По умолчанию Я вернулся с темже грузом

В com порт посылаю wav файл - и тут заморочка, Delay - отрабатывает то больше то меньше...как реализовать правильную подачу данных в com порт GSM модема с задержкой в 20 мс?
Код:
F.LoadFromFile(sAppPath + 'voice\' + 'welcome.raw');
repeat
      NumRead := F.Read(Buf, 320);
      AudioPort.Write(Buf, NumRead);
      Delay(200); - пробовал sleep - вообще не помогает
until ((NumRead = 0) or (CallFinished));
F.Clear;

procedure Delay(Value: Cardinal);
var
  F, N: Cardinal;
begin
  N := 0;
  while N <= (Value div 10) do
  begin
    SleepEx(1, True);
    Application.ProcessMessages;
    Inc(N);
  end;
  F := GetTickCount;
  repeat
    Application.ProcessMessages;
    N := GetTickCount;
  until (N - F >= (Value mod 10)) or (N < F);
end;
Помогите плизззз...
qZED вне форума Ответить с цитированием
Старый 04.03.2014, 21:20   #10
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

Цитата:
Delay - отрабатывает то больше то меньше.
и правильно делает, не используйте слипы, их задержка зависит от загрузки системы и будет плавать тики так.

Что до Gettickcount, лучше использовать QueryPerformanceCounter или KeStallExecutionProcessor.
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
запись всего потока с dvb карты aid33443 Компьютерное железо 0 08.04.2012 01:37
Запись звука с микрофон в wave файл iankov Паскаль, Turbo Pascal, PascalABC.NET 5 31.05.2011 17:50
Запись аудио потока в событие OnBuffer компонента SampleGrabber Jacobson Мультимедиа в Delphi 2 01.08.2010 00:22
Запись аудио потока в SampleGrabber Jacobson Мультимедиа в Delphi 0 21.07.2010 18:57
запись из потока в массив Владимир1988 Помощь студентам 2 06.02.2010 03:08