Recent

Author Topic: [SOLVED] SndFile + Mpg123 + PortAudio examples ?  (Read 16869 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
[SOLVED] SndFile + Mpg123 + PortAudio examples ?
« on: July 13, 2012, 07:04:59 pm »
Hello everybody.

I have installed both lldsndfile and portaudio pascal header.
I can compile and run without problems the examples for each library.  ::)

Now i want to use both library for playing sound (wav , mp3, ...).

After Googling a while, i do not have find any pascal example explaining how to use both libraries together to play sound  :-\ . (but a lot in C/C++  %) ).

Of course i find many examples for each library alone but none working together.

Is there a brave heart who can give me a little code for playing a sound with those libs ?

Examples for portaudio + mpg123 are welcome too.  ::)

Many thanks.

« Last Edit: July 19, 2012, 02:09:46 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Leledumbo

  • Hero Member
  • *****
  • Posts: 8836
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: libsndfile + portaudio example ?
« Reply #1 on: July 13, 2012, 07:51:44 pm »
Quote
After Googling a while, i do not have find any pascal example explaining how to use both libraries together to play sound   . (but a lot in C/C++   ).
No wonder, it's normal since the library is written in that language (C actually) without Pascal consideration at all (mpg123 considers Delphi at least). This is where ability to read C code is useful.

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: libsndfile + portaudio example ?
« Reply #2 on: July 14, 2012, 02:32:03 pm »
@ Leledumbo : Ho, that is very sad  :'(
I gonna try to translate the C example then...

By the way, dynamic library loader for LibSndFile for Lazarus is ready to download, see my new topic.

Cheers and thanks for answers.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: libsndfile + portaudio example ?
« Reply #3 on: July 16, 2012, 12:55:48 pm »
Hum, not lots of answers here.  :-\

OK, if you have some examples in C (or C++)  for portaudio + mpg123 , they are welcome too.  ;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Leledumbo

  • Hero Member
  • *****
  • Posts: 8836
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: libsndfile + portaudio example ?
« Reply #4 on: July 16, 2012, 02:11:54 pm »
Each of those libraries have examples in their source distribution, try translating that, feel free to post the bits you don't understand what their Pascal equivalent here.

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: libsndfile + portaudio example ?
« Reply #5 on: July 16, 2012, 02:17:05 pm »
@ Leledumbo.

Thanks for the answer.

Of course each of those libraries have examples in their source distribution, but none have examples of how to interact with a other lib.

I search for a very basic example who gonna open my mind :
A simple mp3 player who use portaudio + mpg123 or
a simple wav player who use portaudio + sndfile.

Thanks
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Leledumbo

  • Hero Member
  • *****
  • Posts: 8836
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: libsndfile + portaudio example ?
« Reply #6 on: July 16, 2012, 02:26:46 pm »
Ah... I see... that would be no problem, however, assuming they either use the same parameters, or simply convert to the expected format. That's how inter-library communication works most of the time.

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: libsndfile + portaudio example ?
« Reply #7 on: July 16, 2012, 02:36:49 pm »
There is someone here -> http://breakoutbox.de/pascal/pascal.html#mpg123 that looks like he's used PortAudio & Mp123 together, maybe you could download his examples and see how he went about it.

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: libsndfile + portaudio example ?
« Reply #8 on: July 16, 2012, 02:56:11 pm »
@ KpjComp : Thanks but...

The example that Breakoutbox gives for using Portaudio + Mpg123 is only... binary  :'(

They give code for example to use Portaudio alone and Mpg123 alone but the example using the two libraries together is only binary and with no code.

I have sent a mail to Breakoutbox asking them if it is possible to give us the code of the example, even without the graphical stuff, only code to play a Mp3,  but.... he responds me that it was not possible, that he does not have the time to ... (bla, bla, bla).  :'(

So i wait for a example in C and gonna try to translate it.

Till now, i do not find any example, even in C  :'(
« Last Edit: July 18, 2012, 11:21:41 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: libsndfile + portaudio example ?
« Reply #9 on: July 17, 2012, 10:37:00 pm »
Hi FredVs,

Sounds like your doing some good stuff here.

I might see if I can knock something up where is mixes Mpg123 & Portaudio using your dynamic lib headers.  Having a some nice cross-platform audio seems like something a few users on here have asked for.

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: libsndfile + portaudio example ?
« Reply #10 on: July 18, 2012, 02:16:21 am »
Ok, here it is.

It's in no means complete and robust, and will be full of errors I'm sure.  I'm not an audio expert :)  But it does appear to play MP3 Music, and it's working for me on Windows 7.

It's just a simple console App, that plays MP3's using your Mpg123 & Portaudio dynamic libs.

You will need to change the mp3file in the code, of course you could modify this to take the mp3 filename as a parameter.

Anyway, hopefully this might help getting started.   Ideally all this wrapped into a nice class would best, but this console App is just a test.

Also I've done this in blocking mode with it been a console App.

Code: [Select]

program PlayMP3;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this }
  ,lazdyn_mpg123,LazDyn_PortAudio,sysutils,typinfo,CTypes;


procedure Error(e:string);
begin
  raise Exception.Create(e);
end;

procedure pa_check(const err:PaError; s:string);
begin
  if Err = 0 then writeln(s +'  successful')
  else raise Exception.Create(s +' failed, Errorcode = ' +IntToStr( Err)+
   ' '+GetEnumName(typeinfo(PaErrorCode),Err)
   );
end;

const bSize = 65536;
var
  mp3file:string;
  outDev:PaDeviceIndex;
  pDEVinfo : PPaDeviceInfo;
  pAPIinfo : PPaHostApiInfo;
  mh : Tmpg123_handle;
  mhErr : integer;
  rate        : Cardinal;
  channels    : Integer;
  encoding    : Integer;
  NumSampleBlocks:integer;
  outbuf      : array [0..bSize-1] of byte;
  buffer_size : size_t;
  done        : size_t;
  Stream : PPaStream;
  OutputParameters : PaStreamParameters;


procedure CheckMHErr;
begin
  if mhErr <> 0 then
    raise Exception.Create('mpg123 Error: '+inttostr(mhErr));
end;

begin
  try
    mp3file := 'C:\XamppDev\xampp\htdocs\PW\Music\99514Thor_The_Mountain_of_The_Gods.mp3';
    ///////////////////////
    writeln('Loading Mpg123');
    Mp_Load('LibMpg123-32');
    writeln('Mpg123 Loaded');
    ///////////////////////
    writeln('Loading Portaudio');
    Pa_Load('portaudio');
    writeln('Portaudio Loaded');
    //////////////////////////
    writeln('Init mpg123');
    if not (mpg123_init()=MPG123_OK) then Error('mpg123_init failed');

    pa_check(Pa_Initialize(),'Pa_Initialize');

    outDev := Pa_GetDefaultOutputDevice();
    pDEVinfo:= Pa_GetDeviceInfo(outDev);
    pAPIinfo:= Pa_GetHostApiInfo( pDEVinfo^.hostApi);
    writeln('API='+GetEnumName(TypeInfo(PaHostApiTypeId),ord(pAPIinfo^._type)));

    mhErr := 0;
    mh:= mpg123_new( NIL, mhErr); CheckMHErr;
    writeln('Open: '+mp3file);
    mhErr := mpg123_open(mh,pchar(mp3file)); CheckMHErr;

    mhErr := mpg123_getformat( mh, rate, channels, encoding); CheckMHErr;
    writeln('Rate: '+inttostr(rate));
    writeln('Channels: '+inttostr(channels));
    writeln('encoding: '+inttostr(encoding));
    OutputParameters.Device := outdev;
    OutputParameters.ChannelCount := CInt32(channels);
    OutputParameters.SampleFormat :=

      paInt16;
    OutputParameters.SuggestedLatency :=
      (Pa_GetDeviceInfo( OutputParameters.device)^.defaultHighOutputLatency) * 1;
    OutputParameters.HostApiSpecificStreamInfo := nil;

    pa_check(
      Pa_OpenStream(@Stream, nil, @OutputParameters, rate,
      64, paClipOff, nil,nil), 'Pa_OpenStream');

    pa_check(Pa_StartStream(stream),'Pa_StartStream');

    buffer_size := length(outbuf);
    NumSampleBlocks:= 0;
    repeat
      mhErr := mpg123_read( mh, @outbuf[0], buffer_size, done);
      Pa_WriteStream(stream,@outbuf[0],done div 4);
      writeln('Block: '+inttostr(NumSampleBlocks)+' bytes='+inttostr(done));
      inc( NumSampleBlocks);
    until mherr <> MPG123_OK;

    pa_check(Pa_StopStream(stream),'Pa_StopStream');
    Pa_check(Pa_CloseStream(stream),'Pa_CloseStream');

    Pa_Unload();

    mpg123_exit();
    Mp_Unload();
  except
    on E:exception do begin
      writeln('Error:');
      writeln(e.message);
    end;
  end;
  readln;
end.

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: libsndfile + portaudio example ?
« Reply #11 on: July 18, 2012, 12:48:28 pm »
@ KpjComp : Houlala, You save my nights  :P  :P  :P.

Im very exited and gonna try your code now.

Many, many, many, many, many, ..., many Thanks:P  :P  :P

 :D  ;D  :)   :P

PS : By the way, in my exploration of original C codes, the best C to Pascal translator i have founded is this one : C2pas32

http://www.astonshell.com/freeware/c2pas32/

Only console-program (and no source) but he does the work incredibly good.

And for every dummies like me who wants to understand C : here a nice and clear link : From Pascal to C (pdf)

http://web.stonehill.edu/cs1/TE/notespdf.htm


Cheers and, one more time, KpjComp := Greatest;

« Last Edit: July 18, 2012, 01:16:28 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: [SOLVED] libsndfile + portaudio example ?
« Reply #12 on: July 18, 2012, 01:50:36 pm »
No problem Fred_vs,  your header conversions did most the work :)

Like I said it's a little bit hacked up currently.
One area were I really fudged it,.

Code: [Select]
Pa_WriteStream(stream,@outbuf[0],done div 4);

The Div 4 at the time, was really a trial and error, so not really ideal

A Theory I have is that the Audio is 16bit = 2 bytes, and it's in stereo.  So that's 4 bytes per frame buffer, and is the reason for the Div 4.

So I've a feeling Mono MP3's are currently unlikely to work.

Next step is designing a nice framework, I assume the ability to at least FastForward/Rewind etc, and then maybe been able to do special effects and visualizations might be nice.

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: [SOLVED] libsndfile + portaudio example ?
« Reply #13 on: July 18, 2012, 11:17:49 pm »
Yep KpjComp, you did a superb work.  :P
It works like charms with Linux too.  ;D

Now im busy, following your way, to do SndFile playing. (i got it but i have to do some tuning before to show the code  :-[).

Hey man, we have got now all the tools to create wonderful sound applications, with no complex vs other language.

And, i insist, many thanks to KpjComp who open us the way.

Im very,very happy. (i hope it gonna rain a lot cause lots of thing to discover in that marvelous word of Lazarus sound)  :D

Cheeeers  8-)


I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: [SOLVED] libsndfile + portaudio example ?
« Reply #14 on: July 19, 2012, 02:07:40 am »
Yep, i get it  8-)

Here is the code for playing a wav file with PortAudio and SndFile : (under the KpjComp way  ::) )

Code: [Select]
program PlayWAV;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes,lazdyn_LibSndFile,LazDyn_PortAudio,sysutils,typinfo,CTypes;

 
procedure Error(e:string);
begin
  raise Exception.Create(e);
end;

procedure pa_check(const err:PaError; s:string);
begin
  if Err = 0 then writeln(s +'  successful')
  else raise Exception.Create(s +' failed, Errorcode = ' +IntToStr( Err)+
   ' '+GetEnumName(typeinfo(PaErrorCode),Err)
   );
end;


var
   wavfile:string;
   outDev:PaDeviceIndex;
   pDEVinfo : PPaDeviceInfo;
   pAPIinfo : PPaHostApiInfo;
   sh : TSNDFILE_HANDLE;
  // paErr : integer;
   sfInfo: TSF_INFO;
   rate : Cardinal;
   NumSampleBlocks:integer;
   outbuf : array[0..2047] of ctypes.cshort;  //1023 for stereo only !
   Stream : PPaStream;
   OutputParameters : PaStreamParameters;
   BufFrames : Tsf_count_t;
   OutFrames : Tsf_count_t;
 
 
begin
  try
    writeln('');
    writeln('');
    wavfile := '/home/fred/Musique/galaxy.wav';   /// this is in Linux way but feel free to change it for Windows
    ///////////////////////
    writeln('Loading SndFile');

  if sf_Load('/home/fred/Test-PA-SF/lib/LibSndFile-64.so') /// this is a Linux lib, change for Windows DLL if needed
    then writeln('SndFile Loaded')
    else writeln('SndFile not Loaded');

    ///////////////////////
    writeln('Loading Portaudio');

  if pa_Load( '/home/fred/Test-PA-SF/lib/LibPortaudio-64.so')/// this is a Linux lib, change for Windows DLL if needed
     then writeln('Portaudio Loaded')
    else begin
         writeln('Portaudio not Loaded');
         exit;
    end;

    //////////////////////////


    pa_check(Pa_Initialize(),'Pa_Initialize');

    outDev := Pa_GetDefaultOutputDevice();
    pDEVinfo:= Pa_GetDeviceInfo(outDev);
    pAPIinfo:= Pa_GetHostApiInfo( pDEVinfo^.hostApi);

    sh:= sf_open(pchar(wavfile),SFM_READ,sfInfo) ; (* try to open the file *)
  If sh = NIL then
        begin
          writeln( 'ERROR: SoundFile Handle = Nil');
          writeln( sf_strerror( sh));
          writeln( '');
          exit;
        end;
   writeln('');
   writeln('');
   writeln('API='+GetEnumName(TypeInfo(PaHostApiTypeId),ord(pAPIinfo^._type)));
   writeln( '');
   writeln('OK Open: '+wavfile);
   writeln( '');
   writeln( 'Info.channels       = ' +IntToStr( SFinfo.channels));
   writeln( 'Info.format value   = ' +IntToStr( SFinfo.format));
   writeln( 'Info.frames         = ' +IntToStr( SFinfo.frames));
   writeln( 'Info.samplerate     = ' +IntToStr( SFinfo.samplerate));
   writeln( 'Info.sections       = ' +IntToStr( SFinfo.sections));
   writeln( 'Info.seekable       = ' +IntToStr( SFinfo.seekable));
   writeln( '');
    writeln( 'OK, ready to continue...');
 
   sleep(3000); ///// give time to read infos...

     OutputParameters.Device := outdev;
     OutputParameters.channelCount:= CInt32(SFinfo.channels);
     OutputParameters.SampleFormat := paint16 ;
     OutputParameters.SuggestedLatency :=
        (Pa_GetDeviceInfo( OutputParameters.device)^.defaultHighOutputLatency) * 1;
     OutputParameters.HostApiSpecificStreamInfo := nil;
   
     rate := sfInfo.samplerate ;   

   pa_check(Pa_OpenStream(@Stream, nil, @OutputParameters, rate,
            64, paClipOff, nil,nil), 'Pa_OpenStream');

   pa_check(Pa_StartStream(stream),'Pa_StartStream');

     NumSampleBlocks:= 0;
     BufFrames:= length( outbuf);
     OutFrames :=0;
   
  repeat
 
    OutFrames:= sf_read_short( Sh, @outbuf[0], BufFrames);

    Pa_WriteStream(stream,@outbuf[0],OutFrames div 2); ////  OutFrames div 2 :  Why ?

    writeln('Block: '+inttostr(NumSampleBlocks)+'   Bytes Out = '+inttostr(OutFrames));
   
    inc( NumSampleBlocks);

  until  OutFrames < BufFrames;

    writeln('');

    pa_check(Pa_StopStream(stream),'Pa_StopStream');

    Pa_check(Pa_CloseStream(stream),'Pa_CloseStream');
   
    sf_close(sh);

    sf_Unload();
   
    Pa_Unload();

    writeln('');
    writeln('Press Enter to terminate...');

  except
    on E:exception do begin
      writeln('Error:');
      writeln(e.message);
    end;
  end;
  readln;
end.

Have fun.  8-)


PS : @ KpjComp :

Code: [Select]
Pa_WriteStream(stream,@outbuf[0],OutFrames div 2);
Same for me : why ?  :-\

I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018