Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > микширование звука


Автор: marykone 6.5.2006, 19:02
Цитата

Модератор: Пожалуйста, один топик - один вопрос. 


я вас правильно понял дорогой модератор

если да то формат файлов wav 
суть микширования такова необходимо что бы проигрывался основной файл(1.wav) и  с определенной задержкой другой (2.wav) вроде такого пожалуйста помогите
буду рад любой информации !!! и ОСОБЕННО примерам и исходникам 
заранеее спасибо !!!
помогите бедному студенту !!
извините что не так 

Автор: DemoCode 6.5.2006, 19:29
Ответ есть здесь:
http://forum.vingrad.ru/index.php?showtopic=67314&unread=1&view=all&hl= 

Автор: marykone 7.5.2006, 17:01
не очень то  я и нахожу здесь ответ 

Автор: DemoCode 7.5.2006, 19:23
Код

uses  
  ... MMSystem; 

...
 
procedure SendMCICommand(Cmd: string);  
var  
  RetVal: Integer;  
  ErrMsg: array[0..254] of char;  
begin  
  RetVal := mciSendString(PChar(Cmd), nil, 0, 0);  
  if RetVal <> 0 then  
  begin  
    {get message for returned value}  
    mciGetErrorString(RetVal, ErrMsg, 255);  
    MessageDlg(StrPas(ErrMsg), mtError, [mbOK], 0);  
  end;  
end;  

procedure TForm1.FormCreate(Sender: TObject);
begin
    SendMCICommand('open waveaudio shareable');  
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
    SendMCICommand('close waveaudio');  
end;

procedure TForm1.Button1Click(Sender: TObject);  
begin  
   SendMCICommand('play "C:\xyz\BackgroundMusic.wav"');
   Timer1.Enabled:=True;
end;  

procedure TForm1.Timer1Timer(Sender: TObject);
begin
    SendMCICommand('play "C:\xyz\AnotherMusic.wav"');
    Timer1.Enabled:=False; 
end;


Вот немного переделал пример из той темы.
Устанавливаем нужную задержку в Timer1, делаем его enabled в False.
При нажатии на кнопку начинает играть BackgroundMusic.wav, а через заданный интервал времени AnotherMusic.wav 

Автор: marykone 7.5.2006, 20:26
так мне же надо чтобы не одновременно (ну пусть с задержкой ) играли 2 файла а из 2х сделать один извините если не так объяснил задачу 

Автор: Alexeis 11.5.2006, 09:27
marykone, чтоб из двух сделать 1 надо будет сложить звуковые данные приведенные в одинаковый формат(просто сложить значения выборок и затем если надо уменьшить амплитуду результирующей выборки). Пример чтения и записи wav я приводил здесьhttp://forum.vingrad.ru/index.php?showtopic=89826&hl=%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82,and,wav 

Автор: marykone 12.5.2006, 15:21
спасибо --> alexeis1<--  за помощь
еще бы примерчик сложения извини за наглость просто туповат я в delphi 

Автор: Alexeis 12.5.2006, 16:06
Здесь совсем просто!
Пусть имеем два потока данных Strm1, Strm2 (16 бит моно) и переменные W1, W2 типа SmallInt;
Выходной поток RStrm, переменная для хранения суммы S типа SmallInt

Для сумирования необходимо правельно установить указатели потоков 

Код

 Strm1.position := Start1; // начало данных в каждом из потоков от 
 Strm2.position := Start2; //которого начинаем микшировать


Читаем из потоков
Код

Strm1.readBuffer(W1, SizeOf(W1));
Strm2.readBuffer(W2, SizeOf(W2));


Микшируем
Код

S := (W1 + W2) div 2;


Записываем полученную выборку в поток
Код

RStrm.WriteBuffer(S, SizeOf(S));


И повторяем операцию пока не просумируем все выборки(сэмплы)

Далее записываем все все нужные чанки в файловый поток затем
записываем чанк данных (идентификатор размер и Поток данных RStrm) 
Как записывать чанки и данные описанно в статье и кроме того имеется пример создания нового Wav файла и записи в него аудио данных. 
 

Автор: marykone 12.5.2006, 16:27
 а при таком микшированиии 
Цитата

Код

S := (W1 + W2) div 2;


у меня получится эхом ?
а почему деление на 2 ?
извините за глупые вопросы !!!!
спасибо за помощь 
 

Автор: marykone 13.5.2006, 12:16
Цитата

И повторяем операцию пока не просумируем все выборки(сэмплы)

можно пояснить эту строчку (объяснить другими словами или еще лучше на примере) 

Автор: Alexeis 16.5.2006, 12:20
Цитата(marykone @  12.5.2006,  15:27 Найти цитируемый пост)
а почему деление на 2 ?

Если не делить на два то возможно произойдет зашкаливание сэмпла (выход из границ типа), напимер для звука 16 бит если w1 будет +32000 и w2 тоже +32000, то сумма +64000, что в smallInt никак не поместится.

Цитата(marykone @  12.5.2006,  15:27 Найти цитируемый пост)
у меня получится эхом ?

Эхом получится если смешивать правый и левый каналы (я писал этот вариант для моно), а если смешивать различные то все будет нормально.

Вообще суть микширования состоит в линейном сумировании входных сигналов
Y = k1*x1 + k2*x2 + ... + kn*xn;
т.е. сумировании с различным ослаблением (или усилением)
Вариант S := (W1 + W2) div 2;
ни что иное как Y = 1/2 *x1 + 1/2 * x2;
Цитата(marykone @  13.5.2006,  11:16 Найти цитируемый пост)
можно пояснить эту строчку (объяснить другими словами или еще лучше на примере) 


Код

for i := 1 to min(Strm1.size, Strm2.size)
do
  Begin
    Strm1.readBuffer(W1, SizeOf(W1));    
    Strm2.readBuffer(W2, SizeOf(W2));
    S := (W1 + W2) div 2;
    RStrm.WriteBuffer(S, SizeOf(S));
  end;


таим образом  RStrm будет содержать сумарный сигнал длинны наиболее короткой дорожки (из strm1 и strm2) 

Автор: marykone 16.5.2006, 18:59
спасибо огромное тебе alexeis1 очень выручаешь и просвещаешь глупцов вроде меня  

Автор: marykone 18.5.2006, 11:11
дорогой  alexeis1 извини но это опять я
я вот вроде записал микшированный звук с помощью readwave , writewave но у меня возникла проблемма файл который выходящий он не проигрывается не подскажешь ли в чем проблемма
Код

procedure TForm1.Button2Click(Sender: TObject);
var
  f1,f2,fres,temp : tmemorystream;
  i: integer;
  w1,w2,s : SmallInt;

begin
 if r1.ERROR=0 then   // здесь проверяется открылся ли правильно 1 -ый файл для микширования
     opendialog2.Execute;
    r2:=readwave(opendialog2.FileName);
    fres:=tmemorystream.Create;
    f1:=r1.Data;
    f2:=r1.Data;
    for i:=0 to r2.Data.Size do
      Begin
       f1.readBuffer(W1, SizeOf(W1));
       f2.readBuffer(W2, SizeOf(W2));
       S := (W1 + W2) div 2;
       fres.WriteBuffer(S, SizeOf(S));
     end;
   fres.Position:=0;
   got.ERROR:=0;
   got.wAvgBytesPerSec:=r1.wAvgBytesPerSec;
   got.wBitsPerSample:=r1.wBitsPerSample;
   got.wChannels:=r1.wChannels;
   got.wSamplesPerSec:=r1.wSamplesPerSec;
   got.Data:=fres;
   WriteWave('c:\Sample.wav', got);
   showmessage('gotovo');

 
помоги пожалуйста бездарности     smile  

Автор: Alexeis 19.5.2006, 12:42
marykone, Насколько я понял смешиваются левый и правый канал стерео сигнала 16 бит. Если так то размерность цикла неверная 
Цитата(marykone @  18.5.2006,  10:11 Найти цитируемый пост)
for i:=0 to r2.Data.Size do

Размер фрейма 4 байта, Данный цикл читает файл фреймами, а количество фреймов вычисляется по формуле
r2.Data.Size div (wChannels * wBitsPerSample div 8) т.е. число байт данных разделить на число байт фрейма.

кроме того отсчитывая от нуля мы получим неверное число фреймов
Цитата(marykone @  18.5.2006,  10:11 Найти цитируемый пост)
i:=0 

(надо от единицы либо верхнюю границу делать -1)

Зачем было делать две ссылки на один поток также непонятно
Цитата(marykone @  18.5.2006,  10:11 Найти цитируемый пост)
    
   f1:=r1.Data;    
    f2:=r1.Data;    
    for i:=0 to r2.Data.Size do    
      Begin    
       f1.readBuffer(W1, SizeOf(W1));    
       f2.readBuffer(W2, SizeOf(W2));


Можно было просто
 
Код

    f1.readBuffer(W1, SizeOf(W1));    
    f1.readBuffer(W2, SizeOf(W2));

   

более того чтение  производится из пустого потока
Цитата(marykone @  18.5.2006,  10:11 Найти цитируемый пост)

r2:=readwave(opendialog2.FileName);

Поток получили в r2
А ссылку получили на r1(откуда в нем данные не очевидно)

Программы проверяют соответствие указанного размера и действительного и поэтому не проигрывают файлы неполного размера.

Цитата(marykone @  18.5.2006,  10:11 Найти цитируемый пост)
помоги пожалуйста бездарности 

С этим я совершенно не согласен! Все мы учимся, и я в том числе (для меня формат wav тоже новый, просто я сел и за несколько вечеров изучил основные моменты, которые меня интересовали). 
 

Автор: marykone 19.5.2006, 13:25
спасибо alexeis1 
насчет вот этого я проглядел 

Код

    f1:=r1.Data;    
    f2:=r1.Data; 
 
 насчет r1 он у меня на другом баттоне загружается аналогично r2 извини забыл сказать
и смешивание производится не 2 - х каналов а как раз звуковые данные из 1 вав и 2 вав 
у меня получилось только очень и очень криво
суть вообще моего проекта такова нужно в вав 1 (музыка) засунуть другой вав 2 (речь человека) и 
что бы при проигрывании 1 вав не было слышно 2 вав (это метод из стеганографии называется эхо - эфект)  
спасибо за помощь !!!!!!!

Добавлено @ 13:28 
вообще аналогичная задача рассматривается сдесьhttp://www.delphikingdom.com/asp/answer.asp?IDAnswer=42567 вот именно это мне и нужно меня убивает то что человек задал короткий и внятный вопрос а я людям мозги забиваю глупостями 

Автор: Alexeis 19.5.2006, 14:00
Что-то уже я ничего не понял...
Нужно зашифровать один аудио сигнал в другой или
банально смешать два звука для получения общего smile  

Автор: marykone 19.5.2006, 17:06
Нужно зашифровать один аудио сигнал в другой

Добавлено @ 17:08 
я просто перед тем как переходить к основному решил попробовать просто смешать 2 сигнала
если интересно могу про метод этот инфу кинуть 

Автор: marykone 21.5.2006, 15:33
http://forum.vingrad.ru/index.php?showtopic=89826&unread=1&st=0&# 

Автор: marykone 25.5.2006, 15:26
не подскажете как мне сложить 2 файла с задержкой  0,001 сек. 

Автор: Alexeis 12.6.2006, 12:09
Цитата(marykone @  25.5.2006,  14:26 Найти цитируемый пост)
не подскажете как мне сложить 2 файла с задержкой  0,001 сек. 

Пусть имеются два файла в одном формате.
1) читаем данные файлов в память.
2) Создаем третий файл. Записываем в него все нужные заголовки
3) Микшируем данные из n - выборок из 1-го файла, где n = Число выборок в секунду * 0,001, с "тишиной". Записываем в третий файл.
4) Микшируем данные из двух файлов (пока в одном из них не закончатся данные). Записываем в третий файл.
5) Микшируем данные из k - выборок из более длинного файла, где k
 - отаток более длиного файла опать же с "тишиной". Записываем в третий файл.
Я писал с "тишиной", потому, что тишине при различных форматах соответствуют различные числа. 

Автор: marykone 12.6.2006, 13:05
спасибо большое  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)