Lazarus

Programming => Graphics and Multimedia => Audio and Video => Topic started by: Nevada Smith on April 11, 2020, 08:33:02 pm

Title: Calling mpg123_rates in libmpg123 does not work
Post by: Nevada Smith on April 11, 2020, 08:33:02 pm
I am trying to use libmpg123 to play sounds from mp3 files. So far so good, I can play sounds, but I trying to make finer adjustmens and make things prim and proper.
I want to default to paFloat32 (Port Audio) as the sample format. The default for libmpg123 seemed to be int16. I could get float32 working by
Code: Pascal  [Select][+][-]
  1.   mpg123_format(mh, 44100, MPG123_MONO or MPG123_STEREO, MPG123_ENC_FLOAT_32);
  2.   if mhErr <> MPG123_OK then
  3.     DebugLn('Error after mpg123_format ' + IntToStr(mhErr));
However the proper way for doing this seems to be (as per https://www.mpg123.de/api/mpg123__to__out123_8c_source.shtml (https://www.mpg123.de/api/mpg123__to__out123_8c_source.shtml) ) to call mpg123_rates, get the list of rates, and then call mp123_format for each. However I am unable to call mpg123_rates properly. Whatever I do, I get the number (of rates) 0.
This is what I am trying. (I have been trying all sorts of combinations frantically, so it is not really pretty.)
Code: Pascal  [Select][+][-]
  1. var
  2.   Rates: pplong;
  3.   RateCount: integer;
  4.   X, Y: Pointer;
  5.   Count: integer;
  6. begin
  7.   mh:=nil;
  8.   mh := mpg123_new(nil, mhErr);
  9.   if mhErr <> MPG123_OK then
  10.     DebugLn('Error after mpg123_new ' + IntToStr(mhErr));
  11.  
  12.   mhErr := mpg123_format_none(mh);
  13.   if mhErr <> MPG123_OK then
  14.     DebugLn('Error after mpg123_format_none ' + IntToStr(mhErr));
  15.  
  16.   RateCount := 0;
  17.   X := @RateCount;
  18.   //Y := @Rates;
  19.   //Rates := nil;
  20.   mpg123_rates(Rates, X);
  21.   //DebugLn('After mpg123_rates. Rate count is ' + IntToStr(RateCount));
  22.  
 
The C function that is being called:
Code: C  [Select][+][-]
  1. void attribute_align_arg mpg123_rates(const long **list, size_t *number)
  2. {
  3.         if(list   != NULL) *list   = my_rates;
  4.         if(number != NULL) *number = sizeof(my_rates)/sizeof(long);
  5. }

Any help on how to get the call to mpg123_rates work will be really helpful.
Title: Re: Calling mpg123_rates in libmpg123 does not work
Post by: Nevada Smith on April 12, 2020, 07:10:28 am
After much hair-pulling, finally got it working.
I had used https://github.com/Letractively/lazarus-br/blob/master/multimedia/UOS/lazdyn_mpg123.pas (https://github.com/Letractively/lazarus-br/blob/master/multimedia/UOS/lazdyn_mpg123.pas)
The signature of the procedure mpg123_rates was probably incorrect. There are comments placed mentioning that it is untested.
It was:-
Code: Pascal  [Select][+][-]
  1. PLong = Pointer;
  2. pplong = array of PLong;        //pplong in mpg123 means: (a Pointer to) a list of Pointers
  3. {Redacted for clarity. There are lines missing here}
  4. type Tmpg123_rates = procedure( var list : pplong; var number : size_t); cdecl;
Changed it to:-
Code: Pascal  [Select][+][-]
  1. plong = ^clong;
  2. {Redacted for clarity. There are lines missing here}
  3. type Tmpg123_rates = procedure( var list : plong; var number : size_t); cdecl;  
And it was called as:
Code: Pascal  [Select][+][-]
  1.  var
  2.   Rates: plong;
  3.   RateCount: size_t;  
  4. begin
  5.   mpg123_rates(Rates, RateCount);
TinyPortal © 2005-2018