开发者

How to mix Mp3 files

I would like to mix MP3 files with Delphi 2010.

Is this possib开发者_JS百科le? Does anyone know of a component(set) I could use to get this done? Or maybe a runtime library? Any tips from someone with experience mixing MP3 files?


I use newAc:

http://symmetrica.net/newac/

it has a soundmixer component and supports mp3 inputs.

Cheers!


FFmpeg has pascal headers, which apparently you can use from delphi: http://www.iversenit.dk/dev/ffmpeg-headers/

This should allow you to load mp3s or any other file type easily.


Bass.dll, http://www.un4seen.com/


If mixing two mp3 files means mixing the audio signal it is required to decode the mp3 first.

While mp3 contains a decomposed signal structure (fft of the audio signal) two independend mp3 files will probably differ too much in the encoding format to make any attempt of mixing undecoded audio.

For decoding and encoding you need an encoder like lame to convert mp3 to wav files. While streaming (DirectShow Filters) is nice to have a decode, mix, encode should be fairly easy to handle by calling the command line interface.

The lame encoder/decoder binarys are available for windows. Mixing wav is not very complicated as you basically overlay each channels by (a+b)/2.


If your mixing/decoding/playing, I would use the libmad library as it is the fastest most accurate mp3 decoding library as it uses integer math to decode.

There is a delphi pas file for it here:

http://www.koders.com/delphi/fid7D732610F6E36ABA5CE09F5C6D3060FBB74B998E.aspx?s=mp3

Its pretty simple to use. Then you need to mix your two streams, which depends on the data format you choose to work in, I recommend float so you do not loose precision.

for i = 0 to samples do
  out[i] = (in1[i] + in2[i]) * 0.5;

The multiplication by 0.5 is the same as divide by 2, but much faster.


You can also do this using gstreamer


There is few possible choices for MP3 file manipulations: http://www.torry.net/authorsmore.php?id=3243

In my humble opinion, the Audio Tools Library looks most promising one as there are MPEG parsing included ... I have not used any of such tools jet, but it is in my schedule though ...

ALSO, as noted before, MP3 is ompressed format, which means you will need to decompress before actual activities with binary information inside file.

Hope it helps!

Cheers, HX.


Directshow could also be used for this task. There are Delphi header files for Directshow in a package called DSPack.

From the DSPack page:

DSPack is a set of Components and class to write Multimedia Applications using MS Direct Show and DirectX technologies.

For producing an mp3 file as result of overlapping the sound from the two input files, you will need to decompress the two audio files, do the mix and recompress them again. In both cases, you will need to go over the audio samples of both files, treating each channel independently, and averaging the values from input1 and input2 in your output file. It would be something like: outsamples[i] := insamples1[i]/2 + insamples2[i]/2;. For better peformance the expression outsamples[i] := insamples1[i] shr 1 + insamples2[i] shr 1; could be used instead.

For an approach maximizing both, performance and audio quality, I recommend this post, it basically propose using the following expression (A and B are 0-1 normalized audio samples):

Z = 2·A·B if both A<0.5 and B<0.5
Z = 2(A+B) – 2·A·B – 1 otherwise

Other resources that could help:
ffmpeg
lame
razorlame (lame interop for delphi)


you can do this using bass ,Bassenc and lame encoder .

download lame encoder from http://www.rarewares.org/mp3-lame-bundle.php and bass from http://www.un4seen.com/ put bass.dll ,bass.pas,Bassenc.dll,bassenc.pas and lime.exe in same folder as your project exe file. to use sample code put a listbox ,opendialog and two buttons on form

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, bass, bassenc,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  //
  if OpenDialog1.Execute then
    ListBox1.items.add(OpenDialog1.FileName);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  decoder, encoder, newdecoder: dword;
  I, R: Integer;
  buf: array [1 .. 204800] of byte;


begin
  for I := 0 to ListBox1.items.count - 1 do
  begin
    if I = 0 then
    begin
      decoder := BASS_StreamCreateFile(FALSE, PChar(ListBox1.items.strings[0]),
        0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
      encoder := BASS_Encode_Start(decoder,
        'lame.exe --alt-preset standard - fulltrack.mp3',
        BASS_ENCODE_AUTOFREE or BASS_UNICODE, nil, nil);

    end
    else
    begin
      newdecoder := BASS_StreamCreateFile(FALSE, PChar(ListBox1.items.strings[I]
        ), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);



      if not BASS_Encode_SetChannel(encoder, newdecoder) then
      begin
        showmessage(inttostr(BASS_ErrorGetCode));
        BASS_StreamFree(decoder);
        continue;
      end;
      BASS_StreamFree(decoder);

   // free the old decoder
      decoder := newdecoder;
    end;

    R := 1;
    while R > 0 do
    begin
      R := BASS_ChannelGetData(decoder, @buf, sizeof(buf));
    end;

  end;

  BASS_StreamFree(decoder); // free the decoder
  BASS_Encode_Stop(encoder); // stop the encoder
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not BASS_Init(-1, 44100, 0, handle, nil) then
    showmessage('Error initializing audio!');
end;

end.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜