Lazarus

Programming => Graphics and Multimedia => Audio and Video => Topic started by: domasz on March 04, 2022, 12:04:44 am

Title: Audio Component Suite - how convert mp3 to wav?
Post by: domasz on March 04, 2022, 12:04:44 am
There are these units in the ACS: acs_mp3.pas and mp3.pas but I am not sure how to convert mp3 to wav using them.
I couldn't find any example.

I tried this way:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var mp3: TMP3In;
  3.     buff: array of Byte;
  4.     len: Integer;
  5.     sum: Int64;
  6. begin
  7.   mp3 := TMP3In.create(Form1);
  8.   mp3.FileName:='test.mp3';
  9.   mp3.init;
  10.  
  11.   setlength(buff, 4096);  
  12.   sum := 0;
  13.  
  14.   repeat
  15.     len := mp3.GetData(@buff[0], 4096);
  16.  
  17.     sum := sum + len;
  18.  
  19.     if len < 4096 then break;
  20.   until 1=0;
  21.  
  22.  
  23.   mp3.free;
  24.   showmessage(inttostr(sum));
  25.  
  26. end;

[Edited to add code tags: please read How to use the Forums (https://wiki.freepascal.org/Forum).]
Title: Re: Audio Component Suite - how convert mp3 to wav?
Post by: serbod on August 17, 2022, 06:34:15 pm
Code: Pascal  [Select][+][-]
  1. program mp3test;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes, SysUtils, CustApp
  10.   { you can add units after this }
  11.   ,mp3;
  12.  
  13. type
  14.  
  15.   { TMyApplication }
  16.  
  17.   TMyApplication = class(TCustomApplication)
  18.   protected
  19.     procedure DoRun; override;
  20.   public
  21.     constructor Create(TheOwner: TComponent); override;
  22.     destructor Destroy; override;
  23.  
  24.     procedure Test();
  25.   end;
  26.  
  27. type
  28.   TWaveHeader = record
  29.     Marker1: array[0..3] of AnsiChar;
  30.     BytesFollowing: LongInt;
  31.     Marker2: array[0..3] of AnsiChar;
  32.     Marker3: array[0..3] of AnsiChar;
  33.     Fixed1: LongInt;
  34.     FormatTag: Word;
  35.     Channels: Word;
  36.     SampleRate: LongInt;
  37.     BytesPerSecond: LongInt;
  38.     BytesPerSample: Word;
  39.     BitsPerSample: Word;
  40.     Marker4: array[0..3] of AnsiChar;
  41.     DataBytes: LongInt;
  42.   end;
  43.  
  44. procedure CreateWavFile(AFileName: string; ms: TStream; Channels, SampleRate, Resolution: Integer);
  45. var
  46.   DataBytes: Integer;
  47.   WaveHeader: TWaveHeader;
  48.   fsOut: TFileStream;
  49. begin
  50.   DataBytes := ms.Size;
  51.  
  52.   WaveHeader.Marker1 := 'RIFF';
  53.   WaveHeader.BytesFollowing := DataBytes + 36;
  54.   WaveHeader.Marker2 := 'WAVE';
  55.   WaveHeader.Marker3 := 'fmt ';
  56.   WaveHeader.Fixed1 := 16;
  57.   WaveHeader.FormatTag := 1;
  58.   WaveHeader.SampleRate := SampleRate;
  59.   WaveHeader.Channels := Channels;
  60.   WaveHeader.BytesPerSecond := Channels;
  61.   WaveHeader.BytesPerSecond := WaveHeader.BytesPerSecond * SampleRate;
  62.   WaveHeader.BytesPerSecond := WaveHeader.BytesPerSecond * Resolution;
  63.   WaveHeader.BytesPerSecond := WaveHeader.BytesPerSecond div 8;
  64.   WaveHeader.BytesPerSample := Channels * Resolution div 8;
  65.   WaveHeader.BitsPerSample := Resolution;
  66.   WaveHeader.Marker4 := 'data';
  67.   WaveHeader.DataBytes := DataBytes;
  68.  
  69.   if FileExists(AFileName) then
  70.     DeleteFile(AFileName);
  71.   fsOut := TFileStream.Create(AFileName, fmCreate or fmShareDenyNone);
  72.   try
  73.     fsOut.Write(WaveHeader, Sizeof(WaveHeader));
  74.     ms.Position := 0;
  75.     fsOut.CopyFrom(ms, ms.Size);
  76.   finally
  77.     fsOut.Free();
  78.   end;
  79. end;
  80.  
  81. { TMyApplication }
  82.  
  83. procedure TMyApplication.DoRun;
  84. var
  85.   ErrorMsg: String;
  86. begin
  87.  
  88.   { add your program here }
  89.   Test();
  90.  
  91.   // stop program loop
  92.   Terminate;
  93. end;
  94.  
  95. constructor TMyApplication.Create(TheOwner: TComponent);
  96. begin
  97.   inherited Create(TheOwner);
  98.   StopOnException := True;
  99. end;
  100.  
  101. destructor TMyApplication.Destroy;
  102. begin
  103.   inherited Destroy;
  104. end;
  105.  
  106. procedure TMyApplication.Test;
  107. var
  108.   id: TPdmp3Handle;
  109.   fsIn, fsOut: TStream;
  110.   InBuf, OutBuf: TByteArray;
  111.   InSize, OutSize: Integer;
  112.   res: Integer;
  113.   dt: TDateTime;
  114. begin
  115.   if FileExists('out.raw') then
  116.     DeleteFile('out.raw');
  117.  
  118.   fsIn := TFileStream.Create('sample-3s.mp3', fmOpenRead or fmShareDenyNone);
  119.   fsOut := TMemoryStream.Create();
  120.  
  121.   dt := Now();
  122.  
  123.   try
  124.     pdmp3_open_feed(id);
  125.  
  126.     res := PDMP3_NEED_MORE;
  127.     while (res = PDMP3_OK) or (res = PDMP3_NEED_MORE) do
  128.     begin
  129.       // transcode
  130.       inSize := fsIn.Read(InBuf, 2048);
  131.       FillChar(OutBuf, SizeOf(OutBuf), 0);
  132.       res := pdmp3_decode(id, InBuf, inSize, OutBuf, SizeOf(OutBuf), OutSize);
  133.  
  134.       if (res = PDMP3_OK) or (res = PDMP3_NEED_MORE) then
  135.       begin
  136.         fsOut.Write(OutBuf, OutSize);
  137.       end;
  138.     end;
  139.  
  140.     CreateWavFile('out.wav', fsOut, 2, 44100, 16);
  141.  
  142.   finally
  143.     fsOut.Free();
  144.     fsIn.Free();
  145.   end;
  146.  
  147.   WriteLn(FormatDateTime('nn:ss.zzz', Now()-dt));
  148.   ReadLn();
  149. end;
  150.  
  151.  
  152. var
  153.   Application: TMyApplication;
  154. begin
  155.   Application := TMyApplication.Create(nil);
  156.   Application.Title := 'My Application';
  157.   Application.Run;
  158.   Application.Free;
  159. end.
  160.  
TinyPortal © 2005-2018