Раздельная запись звука с левого и правого канала.

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Раздельная запись звука с левого и правого канала.

Сообщение Kvasshtain » 21.10.2011 10:45:52

Народ! Вот тут еще вопрос возник. Есть вот тут такая статья http://www.delphikingdom.com/asp/viewit ... alogid=213 (правда она с вражеского сайта :roll: ) и там типа пишет человек, как звук записывать в wav файл. Так вот мне нуна отдельно писать правый канал, отдельно левый. Как это сделать?
Аватара пользователя
Kvasshtain
новенький
 
Сообщения: 13
Зарегистрирован: 10.01.2011 16:25:49

Re: Раздельная запись звука с левого и правого канала.

Сообщение Bupyc » 21.10.2011 11:15:23

Давным-давно я такое делал. Если я не ошибаюсь, в данных, которые приходят со звуковой карты, поочерёдно идут байты с правого и левого канала.
Т.е. один байт - правый канал, второй байт - левый и т.д.
Bupyc
постоялец
 
Сообщения: 137
Зарегистрирован: 29.08.2007 18:22:42

Re: Раздельная запись звука с левого и правого канала.

Сообщение Kvasshtain » 21.10.2011 15:09:48

Спасибо за ответ.
Вы подтверждаете инфу, которую я уже потом нашел вот здесь http://kazus.ru/articles/52.html.
Но все таки, простите за тупость :? , еще раз.
Т.е. я просто должен читать 16 бит (это в случае 8 битного стерео или 32 бита в случае 16 битного стерео) из wh1.lpData, а потом просто разделить их на две половинки, старшую и младшую, и все, хана :D . Я правильно понял?
Аватара пользователя
Kvasshtain
новенький
 
Сообщения: 13
Зарегистрирован: 10.01.2011 16:25:49

Re: Раздельная запись звука с левого и правого канала.

Сообщение Maxizar » 21.10.2011 19:56:34

Все сводится к тому как вы получаете данные, тобишь в каком виде эти данные представлены. Если это стандартный Wav PCM, то там может быть и более 2-х каналов. Если это именно так, то скажем вот программка, которая может вам помочь разобраться как эти каналы записываются в формате Wav PCM.
Wave File Generator
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Раздельная запись звука с левого и правого канала.

Сообщение Kvasshtain » 24.10.2011 10:10:53

Здорово Maxizar :D , я тут много и долго плясал с бубном вокруг компа и вот чо накумекал :shock: . То чо хранится в address^.lpData^ - это Char, т.е. byte, и в случае 8-и битного стерео тудой пишется то левый то правый канал. И получается, что отличить правый от левого со стороны посторонней подпрограммы невозможно (посторонней по отношению к procedure TformMain.MMProcData(var Message: TMessage), он же обработчик "данные готовы"). А внутри этой функции как я думаю мона сделать так, сказать что типа пускай @wh1 и @wh2 имеют размер по 8 бит, т.е. байт (ну понятно, что в случае 16 битного стерео, будет 16), тогда в @wh1, всегда будет левый, а в @wh2 правый сигналы, вот и все. Но я пока не пробовал. А вообще вопрос к гуру 8) . Нет ли в Waveform Audio Win32 API какой-нибудь функции, которая пишет каналы раздельно в разные места, что бы не городить весь этот огород :roll: ?
Аватара пользователя
Kvasshtain
новенький
 
Сообщения: 13
Зарегистрирован: 10.01.2011 16:25:49

Re: Раздельная запись звука с левого и правого канала.

Сообщение Kvasshtain » 27.10.2011 15:33:50

Добавлено спустя 5 минут 4 секунды:
Ну в 8-ми битном стерео у меня получилось писать данные с обоих каналов. Вот код:

Код: Выделить всё
// обработчик "данные готовы"
procedure TformMain.MMProcData(var Message: TMessage);
var
temp: pWaveHdr;
recorded: integer;
begin
temp:=address;
if address=@wh1 then address:=@wh2 else address:=@wh1;
// если не остановлено, ставим в очередь
if not stop then
waveInAddBuffer(hwi,address,sizeof(TWaveHdr));
recorded:=address.dwBytesRecorded;
// записываем блок
BlockWrite(fOut,(temp.lpData)^,recorded);
if (address.dwBufferLength=1) and (formMain.Channels=2) then //обработка стерео сигнала 8 бит
   Begin
      if address=@wh1 then
        Begin
            label2.Caption:=inttostr(ord(temp^.lpData^));
            TrackBar1.Position:=ord(temp^.lpData^);
        end
      else
         Begin
            label3.Caption:=inttostr(ord(temp^.lpData^));
            TrackBar2.Position:=ord(temp^.lpData^);
         end;
    end;
n:=n+recorded;
formMain.Label1.Caption:=IntToStr(n);
end;


Но как быть с 16 битами? Ведь в temp^.lpData^ лежит всегда только 8-бит, а для 16 битного стерео не понятно какой из 4-х байт относится к какому каналу и к какой половинке, старшей или младшей.
Т.е. я не пойму:

толи сначала младшая половинка левого, потом старшая половинка левого, потом младшая половинка правого, потом старшая половинка правого,

толи сначала младшая половинка левого, потом младшая половинка правого, потом старшая половинка левого, потом старшая половинка правого,

или вообще еще как-нибудь?

И как потом все это хозяйство правильно раздельно прочитать, а потом правильно сшить воедино?

Вот моя гипотеза, которая не работает:

Код: Выделить всё
leftchanal:=true; //для случая 16 битного стерео сделать так как было для 8-и битного нельзя,
// там было так:
// в lpData^ всегда (для 8 и 16 бит) лежит 8 бит, и по этому в случае 8-и бит
// @wh1 всегда лежат данные левого канала, а в @wh2 данные правого канала
// Здесь же имеем следующее:
// Еще раз, в lpData^ всегда (для 8 и 16 бит) лежит 8 бит, но данные теперь 16-бит, а значит
// @wh1 всегда лежит младшая половинка (8-бит), а в @wh1 всегда лежит старшая половинка, но для
// нечетных пар @wh1 - @wh2 это данные левого канала, а для четных - данные правого.
// Флаг-переменная leftchanal - это флаг, установка которого в true значит, что сейчас очередь
// левого канала, и в начале мы его как раз и ставим в true, т.к. первая пара-нечетная, но
// в конце обработки пары мы должны опрокидывать этот флаг в противоположное состояние

if (address.dwBufferLength=2) and (formMain.Channels=2) then //обработка стерео сигнала 16 бит
   Begin
      if address=@wh1 then
        Begin
           loData:=ord(temp^.lpData^);
        end
      else
         Begin
             hiData:=ord(temp^.lpData^);
             leftchanal:=not(leftchanal); // опрокидываем флаг
             label3.Caption:=inttostr((hiData*256 + loData) div 256)
             TrackBar2.Position:=hiData * 256 + loData) div 256;
         end;
end;
[/code]

Ну вот собственно и усо.
Аватара пользователя
Kvasshtain
новенький
 
Сообщения: 13
Зарегистрирован: 10.01.2011 16:25:49


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22

Рейтинг@Mail.ru