Recent

Author Topic: Future Composer Player  (Read 2221 times)

Gigatron

  • Full Member
  • ***
  • Posts: 155
  • Amiga Rulez !!
Future Composer Player
« on: November 09, 2024, 07:26:40 pm »
Hi,

Here is another great player from Amiga called Future Composer (C) Supersero of Superions 1990.(fc1.4)
C language wrapper library for Future Composer audio decoder
Copyright (C) 2008 Michael Schwendt
The library is compiled with Visual studio 2019 for X64 windows i have not linux installed sorry;

Demo music : Bit_arts; project, fc dynamic library in zip format are attached;
You can download FC 1.3 or FC 1.4 musics here :
https://modland.com/pub/modules/Future%20Composer%201.3/
https://modland.com/pub/modules/Future%20Composer%201.4/


Main Unit :
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, fc_lib,
  9.   mmsystem, windows;
  10.  
  11. const
  12.   Channels = 2;
  13.   BitsPerSample = 16;
  14.   SampleRate = 44100; // Nombre d'Ă©chantillons par seconde
  15.   BufSize = 8192;    // Taille du tampon audio x 2
  16.   BufferCount = 2;
  17.  
  18. type
  19.   { TForm1 }
  20.  
  21.   TForm1 = class(TForm)
  22.     Timer1: TTimer;
  23.     procedure FormCreate(Sender: TObject);
  24.     procedure FormShow(Sender: TObject);
  25.     procedure Timer1Timer(Sender: TObject);
  26.   private
  27.     buffers: array[0..BufferCount-1] of array[0..BufSize-1] of   Byte;
  28.     waveHeaders: array[0..BufferCount-1] of TWaveHdr;
  29.     currentBuffer: Integer;
  30.   public
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.   waveOut: HWAVEOUT;
  36.   fc_mus: Pointer;
  37.   ok_flag: Boolean = false;
  38.   fsize : integer;
  39.  
  40. implementation
  41.  
  42. {$R *.lfm}
  43.  
  44. procedure HandleError(const Str: PAnsiChar);
  45. begin
  46.   if Str <> nil then
  47.   begin
  48.     ShowMessage('Error: ' + Str);
  49.     Halt(1);
  50.   end;
  51. end;
  52.  
  53. procedure FillBuffer(bufferIndex: Integer);
  54.  
  55. begin
  56.   if ok_flag then
  57.   begin
  58.      // ShowMessage('Remplissage buffer ici');
  59.      bufferIndex := Form1.currentBuffer;
  60.      fc14dec_buffer_fill(fc_mus, @Form1.buffers[bufferIndex][0], BufSize );
  61.      end;
  62. end;
  63.  
  64. function WaveOutCallback(hwo: HWAVEOUT; uMsg: UINT; dwInstance, dwParam1, dwParam2: DWORD_PTR): DWORD; stdcall;
  65. begin
  66.   if uMsg = WOM_DONE then
  67.   begin
  68.     FillBuffer(Form1.currentBuffer);
  69.     waveOutWrite(waveOut, @Form1.waveHeaders[Form1.currentBuffer], SizeOf(TWaveHdr));
  70.     Form1.currentBuffer := (Form1.currentBuffer + 1) mod BufferCount;
  71.   end;
  72.   Result := 0;
  73. end;
  74.  
  75. procedure InitAudio;
  76. var
  77.   wFormat: TWaveFormatEx;
  78.   i: Integer;
  79. begin
  80.   SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_LOWEST);
  81.  
  82.   with wFormat do
  83.   begin
  84.     wFormatTag := WAVE_FORMAT_PCM;
  85.     nChannels := Channels;
  86.     nSamplesPerSec := SampleRate;
  87.     wBitsPerSample := BitsPerSample;
  88.     nBlockAlign := (wBitsPerSample * nChannels) div 8;
  89.     nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
  90.     cbSize := 0;
  91.   end;
  92.  
  93.   if waveOutOpen(@waveOut, WAVE_MAPPER, @wFormat, QWORD(@WaveOutCallback), 0, CALLBACK_FUNCTION) <> MMSYSERR_NOERROR then
  94.     raise Exception.Create('Erreur lors de l''ouverture du pĂ©riphĂ©rique audio');
  95.  
  96.   // PrĂ©paration des tampons
  97.   for i := 0 to BufferCount - 1 do
  98.   begin
  99.     ZeroMemory(@Form1.waveHeaders[i], SizeOf(TWaveHdr));
  100.     with Form1.waveHeaders[i] do
  101.     begin
  102.       lpData := @Form1.buffers[i][0];
  103.       dwBufferLength := BufSize  ;
  104.       dwFlags := 0;
  105.        FillBuffer(i);
  106.     end;
  107.     waveOutPrepareHeader(waveOut, @Form1.waveHeaders[i], SizeOf(TWaveHdr));
  108.   end;
  109.     Form1.currentBuffer := 0;
  110.     for i := 0 to BufferCount - 1 do
  111.      begin
  112.      FillBuffer(i);
  113.      waveOutWrite(waveOut, @Form1.waveHeaders[i], SizeOf(TWaveHdr));
  114.     end;
  115. end;
  116.  
  117. procedure LoadBinaryFileToBuffer(const FileName: string; var Buffer:   TBytes);
  118. var
  119.   MemoryStream: TMemoryStream;
  120. begin
  121.   MemoryStream := TMemoryStream.Create;
  122.   try
  123.     MemoryStream.LoadFromFile(FileName);
  124.     SetLength(Buffer, MemoryStream.Size); // Ajuste la taille du buffer
  125.     MemoryStream.ReadBuffer(Buffer[0], MemoryStream.Size);
  126.     fsize := MemoryStream.Size;
  127.   finally
  128.     MemoryStream.Free;
  129.   end;
  130. end;
  131.  
  132. procedure TForm1.FormCreate(Sender: TObject);
  133. var
  134.   Buffer: array of Byte;
  135.   FileName: string;
  136.  begin
  137.  
  138.   FileName := 'billy_the_kid.fc';
  139.  
  140.   try
  141.     LoadBinaryFileToBuffer(FileName, Buffer);
  142.  
  143.   except
  144.     on E: Exception do
  145.       ShowMessage('Erreur : ' );
  146.   end;
  147.  
  148.       // Initialisation du dĂ©codeur
  149.       fc_mus := fc14dec_new;
  150.       fc14dec_init(fc_mus, PByte(Buffer), fsize);
  151.       fc14dec_mixer_init(fc_mus, 44100, 16, 2, 0);
  152.       fc14dec_enableNtsc(fc_mus,false);
  153.  
  154.   end;
  155.  
  156. procedure TForm1.FormShow(Sender: TObject);
  157. begin
  158.      InitAudio;
  159.      ok_flag := true;
  160.  
  161. end;
  162.  
  163.  
  164. procedure TForm1.Timer1Timer(Sender: TObject);
  165. begin
  166.  
  167. end;
  168.  
  169. end.
  170.  
Fc library unit :
Code: Pascal  [Select][+][-]
  1. unit fc_lib;
  2.  
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6. interface
  7.  
  8. uses
  9.     windows;
  10.  
  11.   const
  12.     FCLIB = 'futurecomposer.dll';
  13.  
  14. //type
  15. //  TFC = class(TPaulaPlayer)
  16. //  private
  17. //    _dummyVoices: array[0..3] of TPaulaVoice;
  18. //
  19. //    input: PByte;
  20. //    inputLen: word;
  21. //
  22. //    var silenceData: array[0..7] of Byte;
  23. //    var periods: array[0..(5+6)*12+4-1] of Word;
  24. //    var SMOD_waveInfo: array[0..47*4-1] of Word;
  25. //    var SMOD_waveforms: array of Byte;
  26. //
  27. //
  28. //  public
  29. //    songEnd: Boolean;  // whether song end has been reached
  30. //    isSMOD: Boolean;   // whether file is in Future Composer 1.0 - 1.3 format
  31. //    isFC14: Boolean;   // whether file is in Future Composer 1.4 format
  32. //
  33. //    formatName: string;
  34. //    const SMOD_FORMAT_NAME = 'Future Composer 1.0-1.3';
  35. //    const FC14_FORMAT_NAME = 'Future Composer 1.4';
  36. //    const UNKNOWN_FORMAT_NAME = 'Unknown Format';
  37. //
  38. //    const SMOD_SONGTAB_OFFSET = $0064;      // 100
  39. //    const FC14_SMPHEADERS_OFFSET = $0028;   // 40
  40. //    const FC14_WAVEHEADERS_OFFSET = $0064;  // 100
  41. //    const FC14_SONGTAB_OFFSET = $00B4;      // 180
  42. //
  43. //    const TRACKTAB_ENTRY_LENGTH = $000D;    // 3*4+1
  44. //    const PATTERN_LENGTH = $0040;           // 32*2
  45. //    const PATTERN_BREAK = $49;
  46. //
  47. //    const SEQ_END = $E1;
  48. //
  49. //    const SNDMOD_LOOP = $E0;
  50. //    const SNDMOD_END = SEQ_END;
  51. //    const SNDMOD_SETWAVE = $E2;
  52. //    const SNDMOD_CHANGEWAVE = $E4;
  53. //    const SNDMOD_NEWVIB = $E3;
  54. //    const SNDMOD_SUSTAIN = $E8;
  55. //    const SNDMOD_NEWSEQ = $E7;
  56. //    const SNDMOD_SETPACKWAVE = $E9;
  57. //    const SNDMOD_PITCHBEND = $EA;
  58. //
  59. //    const ENVELOPE_LOOP = $E0;
  60. //    const ENVELOPE_END = SEQ_END;
  61. //    const ENVELOPE_SUSTAIN = $E8;
  62. //    const ENVELOPE_SLIDE = $EA;
  63. //
  64. //
  65. //
  66. //  end;
  67.  
  68. function  fc14dec_new: Pointer; cdecl; external FCLIB;
  69. procedure fc14dec_delete(decoder: Pointer); cdecl; external FCLIB;
  70. function  fc14dec_detect(decoder: Pointer; buffer: Pointer; length: Cardinal): Integer; cdecl; external FCLIB;
  71. function  fc14dec_init(decoder: Pointer; buffer: Pointer; length: Cardinal): Integer; cdecl; external FCLIB;
  72. procedure fc14dec_restart(decoder: Pointer); cdecl; external FCLIB;
  73. procedure fc14dec_mixer_init(decoder: Pointer; frequency: Integer; precision: Integer; channels: Integer; zero: Integer); cdecl; external FCLIB;
  74. function  fc14dec_song_end(decoder: Pointer): Integer; cdecl; external FCLIB;
  75. function  fc14dec_duration(decoder: Pointer): Cardinal; cdecl; external FCLIB;
  76. procedure fc14dec_seek(decoder: Pointer; ms: LongInt); cdecl; external FCLIB;
  77. function  fc14dec_format_name(decoder: Pointer): PChar; cdecl; external FCLIB;
  78. function  fc14dec_buffer_fill(decoder: Pointer; buffer: Pointer; length: UINT): UINT; cdecl; external FCLIB;
  79. function  fc14dec_isFC14(decoder: Pointer): Integer; cdecl; external FCLIB;
  80. procedure fc14dec_enableNtsc(decoder: Pointer; isEnabled: Boolean); cdecl; external FCLIB;
  81.  
  82. implementation
  83.  
  84. end.

« Last Edit: November 09, 2024, 07:47:26 pm by Gigatron »
Sub Quantum Technology ! Gigatron 68000 Colmar France;

hukka

  • New Member
  • *
  • Posts: 33
    • Github
Re: Future Composer Player
« Reply #1 on: November 10, 2024, 05:18:10 am »
I have sources for a native FreePascal FC replayer at: https://github.com/hukkax/CaniNES/tree/main/src/basement/playroutines

Gigatron

  • Full Member
  • ***
  • Posts: 155
  • Amiga Rulez !!
Re: Future Composer Player
« Reply #2 on: November 11, 2024, 09:19:06 pm »
I have sources for a native FreePascal FC replayer at: https://github.com/hukkax/CaniNES/tree/main/src/basement/playroutines
Thank you @hukka , interesting to understand how this FC library work in FreePascal;

Sub Quantum Technology ! Gigatron 68000 Colmar France;

TRon

  • Hero Member
  • *****
  • Posts: 3650
Re: Future Composer Player
« Reply #3 on: November 12, 2024, 09:56:50 am »
Very nice hukka.

It required some work to get a (more or less) standalone frame-decoder ( Linux only, using libao).

Original license(s) applies.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Guva

  • Full Member
  • ***
  • Posts: 117
Re: Future Composer Player
« Reply #4 on: November 25, 2024, 07:39:55 am »
I will make my contribution

However, there is a problem . For some reason it only works in {$mode delphi}

main unit
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode delphi}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, raudio, fc_lib;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Memo1: TMemo;
  17.     OpenDialog1: TOpenDialog;
  18.     procedure Button1Click(Sender: TObject);
  19.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  20.     procedure FormCreate(Sender: TObject);
  21.   private
  22.  
  23.   public
  24.  
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.   stream: TAudioStream;
  30.   fc_mus: pfc14;
  31.   fsize : integer;
  32.  
  33. const
  34.   SampleRate = 44100;
  35.   BufferSize = 8192 ;
  36.   SampleSize = 16;
  37.   Channels = 2;
  38.  
  39. implementation
  40.  
  41. {$R *.lfm}
  42.  
  43. procedure FillAudio(bufferData: Pointer; frames: LongWord); cdecl;
  44. begin
  45.   fc14dec_buffer_fill(fc_mus, bufferData, frames * 4);
  46. end;
  47.  
  48. { TForm1 }
  49.  
  50. procedure TForm1.FormCreate(Sender: TObject);
  51. var thelib, ordir: string;
  52. begin
  53.   ordir := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)));
  54.   {$IFDEF windows}
  55.   thelib := 'fc14audiodecoder.dll';
  56.   {$Else}
  57.   thelib := 'libfc14audiodecoder.so';
  58.   {$ENDIF}
  59.  
  60.   memo1.Lines.Clear;
  61.  
  62.   if fc14_Load(ordir + thelib) then
  63.   begin
  64.     fc_mus := fc14dec_new;
  65.   end;
  66.  
  67.    {$IFDEF windows}
  68.    thelib := 'raylib.dll';
  69.    {$Else}
  70.    thelib := 'libraylib.so';
  71.    {$ENDIF}
  72.  
  73.    if rAudio_Load(ordir + thelib) then
  74.    InitAudioDevice() else
  75.    writeln('libraylib load error.');
  76.  
  77.    SetAudioStreamBufferSizeDefault(BufferSize);
  78.    Stream := LoadAudioStream(SampleRate, SampleSize, Channels);
  79.    SetAudioStreamCallback(Stream,@FillAudio);
  80. end;
  81.  
  82. procedure TForm1.Button1Click(Sender: TObject);
  83. var
  84.   MemBuffer: TMemoryStream;
  85. begin
  86.   if openDialog1.Execute then
  87.   begin
  88.     MemBuffer := TMemoryStream.Create;
  89.     try
  90.       MemBuffer.LoadFromFile(OpenDialog1.FileName);
  91.       fc14dec_init(fc_mus, MemBuffer.Memory, MemBuffer.Size);
  92.       fc14dec_mixer_init(fc_mus, SampleRate, SampleSize, Channels, 0);
  93.       PlayAudioStream(stream);
  94.       memo1.Lines.Add('Version: ' + fc14dec_format_name(fc_mus));
  95.       memo1.Lines.Add('Duration: ' + IntToStr(fc14dec_duration(fc_mus)));
  96.       memo1.Lines.Add(' ');
  97.     except
  98.       on E: Exception do
  99.       ShowMessage('ERROR : ' );
  100.     end;
  101.      MemBuffer.Free;
  102.   end;
  103. end;
  104.  
  105. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  106. begin
  107.   StopAudioStream(stream);
  108. end;
  109.  
  110. end.      
  111.  
« Last Edit: November 25, 2024, 07:45:09 am by Guva »

Guva

  • Full Member
  • ***
  • Posts: 117
Re: Future Composer Player
« Reply #5 on: November 25, 2024, 07:40:44 am »
raylib used only audio

Code: Pascal  [Select][+][-]
  1. unit raudio;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   DynLibs, SysUtils, CTypes;
  9.  
  10. const
  11. {$IFDEF windows}
  12.   RAUDIO_LIB_NAME = 'raylib.dll';
  13. {$ENDIF}
  14. {$IFDEF unix}
  15.  {$IFDEF darwin}
  16.   RAUDIO_LIB_NAME = 'libraylib.dylib';
  17.  {$ELSE}
  18.   RAUDIO_LIB_NAME = 'libraylib.so';
  19.  {$ENDIF}
  20. {$ENDIF}
  21.  
  22. type
  23.   (* Wave, audio wave data *)
  24.   PWave = ^TWave;
  25.   TWave = record
  26.       frameCount : LongWord;   // Total number of frames (considering channels)
  27.       sampleRate : LongWord;   // Frequency (samples per second)
  28.       sampleSize : LongWord;   // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
  29.       channels   : LongWord;   // Number of channels (1-mono, 2-stereo, ...)
  30.       data       : Pointer;    // Buffer data pointer
  31.     end;
  32.  
  33.   PrAudioBuffer = ^TrAudioBuffer;
  34.   TrAudioBuffer = record end;
  35.  
  36.   PrAudioProcessor = ^TrAudioProcessor;
  37.   TrAudioProcessor = record end;
  38.  
  39.   (* AudioStream, custom audio stream *)
  40.   PAudioStream = ^TAudioStream;
  41.   TAudioStream = record
  42.       buffer     : PrAudioBuffer;    // Pointer to internal data used by the audio system
  43.       processor  : PrAudioProcessor; // Pointer to internal data processor, useful for audio effects
  44.       sampleRate : LongWord;         // Frequency (samples per second)
  45.       sampleSize : LongWord;         // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
  46.       channels   : LongWord;         // Number of channels (1-mono, 2-stereo, ...)
  47.     end;
  48.  
  49.   (* Sound *)
  50.   PSound = ^TSound;
  51.   TSound = record
  52.       stream     : TAudioStream;    // Audio stream
  53.       frameCount : LongWord;        // Total number of frames (considering channels)
  54.     end;
  55.  
  56.   (*Music, audio stream, anything longer than ~10 seconds should be streamed *)
  57.   PMusic = ^TMusic;
  58.   TMusic = record
  59.       stream     : TAudioStream; // Audio stream
  60.       frameCount : LongWord;     // Total number of frames (considering channels)
  61.       looping    : Boolean;      // Music looping enable
  62.       ctxType    : Integer;      // Type of music context (audio filetype)
  63.       ctxData    : Pointer;      // Audio context data, depends on type
  64.     end;
  65.  
  66. type
  67.   PAudioCallback = ^TAudioCallback;
  68.   TAudioCallback = procedure (bufferData: Pointer; frames: LongWord); cdecl;
  69.  
  70. var
  71.   (* Audio device management functions *)
  72.   InitAudioDevice: procedure(); cdecl;  // Initialize audio device and context
  73.   CloseAudioDevice: procedure(); cdecl; // Close the audio device and context
  74.   IsAudioDeviceReady: function(): boolean; cdecl; // Check if audio device has been initialized successfully
  75.   SetMasterVolume: procedure(volume: single); cdecl; // Set master volume (listener)
  76.   GetMasterVolume: function(): single; cdecl; // Get master volume (listener)
  77.   (* Wave/Sound loading/unloading functions *)
  78.   LoadWave: function(const fileName: PChar): TWave; cdecl;
  79.   LoadWaveFromMemory: function (const fileType: PChar; const fileData: PByte; dataSize: Integer): TWave; cdecl;
  80.   IsWaveValid: function(wave: TWave): Boolean; cdecl;
  81.   LoadSound: function(const fileName: PChar): TSound; cdecl;
  82.   LoadSoundFromWave: function(wave: TWave): TSound; cdecl;
  83.   LoadSoundAlias: function(source: TSound): TSound; cdecl;
  84.   IsSoundValid: function(sound: TSound): Boolean; cdecl;
  85.   UpdateSound: procedure(sound: TSound; const data: Pointer; sampleCount: Integer); cdecl;
  86.   UnloadWave: procedure(wave: TWave); cdecl;
  87.   UnloadSound: procedure(sound: TSound); cdecl;
  88.   UnloadSoundAlias: procedure(alias: TSound); cdecl;
  89.   ExportWave: function(wave: TWave; const fileName: PChar): Boolean; cdecl;
  90.   ExportWaveAsCode: function(wave: TWave; const fileName: PChar): Boolean; cdecl;
  91.   (* Wave/Sound management functions *)
  92.   PlaySound: procedure(sound: TSound); cdecl;
  93.   StopSound: procedure(sound: TSound); cdecl;
  94.   PauseSound: procedure(sound: TSound); cdecl;
  95.   ResumeSound: procedure(sound: TSound); cdecl;
  96.   IsSoundPlaying: function(sound: TSound): Boolean; cdecl;
  97.   SetSoundVolume: procedure(sound: TSound; volume: Single); cdecl;
  98.   SetSoundPitch: procedure(sound: TSound; pitch: Single); cdecl;
  99.   SetSoundPan: procedure(sound: TSound; pan: Single); cdecl;
  100.   WaveCopy: function(wave: TWave): TWave; cdecl;
  101.   WaveCrop: procedure(wave: PWave; initFrame, finalFrame: Integer); cdecl;
  102.   WaveFormat: procedure(wave: PWave; sampleRate, sampleSize, channels: Integer); cdecl;
  103.   LoadWaveSamples: function(wave: TWave): PSingle; cdecl;
  104.   UnloadWaveSamples: procedure(samples: PSingle); cdecl;
  105.   (* Music management functions *)
  106.   LoadMusicStream: function(const fileName: PChar): TMusic; cdecl;
  107.   LoadMusicStreamFromMemory: function(const fileType: PChar; const data: PByte; dataSize: Integer): TMusic; cdecl;
  108.   IsMusicValid: function(music: TMusic): Boolean; cdecl;
  109.   UnloadMusicStream: procedure(music: TMusic); cdecl;
  110.   PlayMusicStream: procedure(music: TMusic); cdecl;
  111.   IsMusicStreamPlaying: function(music: TMusic): Boolean; cdecl;
  112.   Upda]"]>BlockedsicStream: procedure(music: TMusic); cdecl;
  113.   StopMusicStream: procedure(music: TMusic); cdecl;
  114.   PauseMusicStream: procedure(music: TMusic); cdecl;
  115.   ResumeMusicStream: procedure(music: TMusic); cdecl;
  116.   SeekMusicStream: procedure(music: TMusic; position: Single); cdecl;
  117.   SetMusicVolume: procedure(music: TMusic; volume: Single); cdecl;
  118.   SetMusicPitch: procedure(music: TMusic; pitch: Single); cdecl;
  119.   SetMusicPan: procedure(music: TMusic; pan: Single); cdecl;
  120.   GetMusicTimeLength: function(music: TMusic): Single; cdecl;
  121.   GetMusicTimePlayed: function(music: TMusic): Single; cdecl;
  122.   (* AudioStream management functions *)
  123.   LoadAudioStream: function(sampleRate, sampleSize, channels: LongWord): TAudioStream; cdecl;
  124.   IsAudioStreamValid: function(stream: TAudioStream): boolean; cdecl;
  125.   UnloadAudioStream: procedure(stream: TAudioStream); cdecl;
  126.   UpdateAudioStream: procedure(stream: TAudioStream; const data: Pointer; frameCount: Integer); cdecl;
  127.   IsAudioStreamProcessed: function(stream: TAudioStream): Boolean; cdecl;
  128.   PlayAudioStream: procedure(stream: TAudioStream); cdecl;
  129.   PauseAudioStream: procedure(stream: TAudioStream); cdecl;
  130.   ResumeAudioStream: procedure(stream: TAudioStream); cdecl;
  131.   IsAudioStreamPlaying: function(stream: TAudioStream): Boolean; cdecl;
  132.   StopAudioStream: procedure(stream: TAudioStream); cdecl;
  133.   SetAudioStreamVolume: procedure(stream: TAudioStream; volume: Single); cdecl;
  134.   SetAudioStreamPitch: procedure(stream: TAudioStream; pitch: Single); cdecl;
  135.   SetAudioStreamPan: procedure(stream: TAudioStream; pan: Single); cdecl;
  136.   SetAudioStreamBufferSizeDefault: procedure(size: Integer); cdecl;
  137.   SetAudioStreamCallback: procedure(stream: TAudioStream; callback: TAudioCallback); cdecl;
  138.  
  139.   AttachAudioStreamProcessor: procedure(stream: TAudioStream; processor: TAudioCallback); cdecl;
  140.   DetachAudioStreamProcessor: procedure(stream: TAudioStream; processor: TAudioCallback); cdecl;
  141.   AttachAudioMixedProcessor: procedure(processor: TAudioCallback); cdecl;
  142.   DetachAudioMixedProcessor: procedure(processor: TAudioCallback); cdecl;
  143.  
  144.  
  145. {Special function for dynamic loading of lib ...}
  146. var
  147.   rAudio_Handle: TLibHandle = dynlibs.NilHandle;
  148.   ReferenceCounter: cardinal = 0;  // Reference counter
  149.  
  150. function rAudio_IsLoaded: Boolean; inline;
  151. function rAudio_Load(const libfilename: string): Boolean; // load the lib
  152. procedure rAudio_Unload(); // unload and frees the lib from memory : do not forget to call it before close application.
  153.  
  154.  
  155. implementation
  156.  
  157. function rAudio_IsLoaded: Boolean;
  158. begin
  159.   Result := (rAudio_Handle <> dynlibs.NilHandle);
  160. end;
  161.  
  162. function rAudio_Load(const libfilename: string): Boolean;
  163. var
  164. thelib: string;
  165. begin
  166.   Result := False;
  167.   if rAudio_Handle<>0 then
  168.   begin
  169.     Inc(ReferenceCounter);
  170.     result:=true {is it already there ?}
  171.   end else
  172.   begin
  173.   {go & load the library}
  174.    if Length(libfilename) = 0 then thelib := RAUDIO_LIB_NAME else
  175.    thelib := libfilename;
  176.     rAudio_Handle:=DynLibs.LoadLibrary(thelib); // obtain the handle we want
  177.    if rAudio_Handle <> DynLibs.NilHandle then
  178.   begin {now we tie the functions to the VARs from above}
  179.     (* Audio device management functions *)
  180.     Pointer(InitAudioDevice):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('InitAudioDevice'));
  181.     Pointer(CloseAudioDevice):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('CloseAudioDevice'));
  182.     Pointer(IsAudioDeviceReady):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsAudioDeviceReady'));
  183.     Pointer(SetMasterVolume):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetMasterVolume'));
  184.     Pointer(GetMasterVolume):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('GetMasterVolume'));
  185.     (* Wave/Sound loading/unloading functions *)
  186.     Pointer(LoadWave):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadWave'));
  187.     Pointer(LoadWaveFromMemory):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadWaveFromMemory'));
  188.     Pointer(IsWaveValid):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsWaveValid'));
  189.     Pointer(LoadSound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadSound'));
  190.     Pointer(LoadSoundFromWave):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadSoundFromWave'));
  191.     Pointer(LoadSoundAlias):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadSoundAlias'));
  192.     Pointer(IsSoundValid):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsSoundValid'));
  193.     Pointer(UpdateSound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UpdateSound'));
  194.     Pointer(UnloadWave):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadWave'));
  195.     Pointer(UnloadSound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadSound'));
  196.     Pointer(UnloadSoundAlias):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadSoundAlias'));
  197.     Pointer(ExportWave):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadSoundAlias'));
  198.     Pointer(ExportWaveAsCode):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadSoundAlias'));
  199.     (* Wave/Sound management functions *)
  200.     Pointer(PlaySound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('PlaySound'));
  201.     Pointer(StopSound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('StopSound'));
  202.     Pointer(PauseSound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('PauseSound'));
  203.     Pointer(ResumeSound):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('ResumeSound'));
  204.     Pointer(IsSoundPlaying):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsSoundPlaying'));
  205.     Pointer(SetSoundVolume):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetSoundVolume'));
  206.     Pointer(SetSoundPitch):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetSoundPitch'));
  207.     Pointer(SetSoundPan):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetSoundPan'));
  208.     Pointer(WaveCopy):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('WaveCopy'));
  209.     Pointer(WaveCrop):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('WaveCrop'));
  210.     Pointer(WaveFormat):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('WaveFormat'));
  211.     Pointer(LoadWaveSamples):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadWaveSamples'));
  212.     Pointer(UnloadWaveSamples):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadWaveSamples'));
  213.     (* Music management functions *)
  214.     Pointer(LoadMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadMusicStream'));
  215.     Pointer(LoadMusicStreamFromMemory):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadMusicStreamFromMemory'));
  216.     Pointer(IsMusicValid):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsMusicValid'));
  217.     Pointer(UnloadMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadMusicStream'));
  218.     Pointer(PlayMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('PlayMusicStream'));
  219.     Pointer(IsMusicStreamPlaying):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsMusicStreamPlaying'));
  220.     Pointer(Upda]"]>BlockedsicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('Upda]"]>BlockedsicStream'));
  221.     Pointer(StopMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('StopMusicStream'));
  222.     Pointer(PauseMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('PauseMusicStream'));
  223.     Pointer(ResumeMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('ResumeMusicStream'));
  224.     Pointer(SeekMusicStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SeekMusicStream'));
  225.     Pointer(SetMusicVolume):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetMusicVolume'));
  226.     Pointer(SetMusicPitch):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetMusicPitch'));
  227.     Pointer(SetMusicPan):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetMusicPan'));
  228.     Pointer(GetMusicTimeLength):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('GetMusicTimeLength'));
  229.     Pointer(GetMusicTimePlayed):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('GetMusicTimePlayed'));
  230.     (* AudioStream management functions *)
  231.     Pointer(LoadAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('LoadAudioStream'));
  232.     Pointer(IsAudioStreamValid):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsAudioStreamValid'));
  233.     Pointer(UnloadAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UnloadAudioStream'));
  234.     Pointer(UpdateAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('UpdateAudioStream'));
  235.     Pointer(IsAudioStreamProcessed):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsAudioStreamProcessed'));
  236.     Pointer(PlayAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('PlayAudioStream'));
  237.     Pointer(PauseAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('PauseAudioStream'));
  238.     Pointer(ResumeAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('ResumeAudioStream'));
  239.     Pointer(IsAudioStreamPlaying):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('IsAudioStreamPlaying'));
  240.     Pointer(StopAudioStream):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('StopAudioStream'));
  241.     Pointer(SetAudioStreamVolume):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetAudioStreamVolume'));
  242.     Pointer(SetAudioStreamPitch):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetAudioStreamPitch'));
  243.     Pointer(SetAudioStreamPan):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetAudioStreamPan'));
  244.     Pointer(SetAudioStreamBufferSizeDefault):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetAudioStreamBufferSizeDefault'));
  245.     Pointer(SetAudioStreamCallback):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('SetAudioStreamCallback'));
  246.  
  247.     Pointer(AttachAudioStreamProcessor):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('AttachAudioStreamProcessor'));
  248.     Pointer(DetachAudioStreamProcessor):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('DetachAudioStreamProcessor'));
  249.     Pointer(AttachAudioMixedProcessor):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('AttachAudioMixedProcessor'));
  250.     Pointer(DetachAudioMixedProcessor):=DynLibs.GetProcedureAddress(rAudio_Handle,PChar('DetachAudioMixedProcessor'));
  251.   end;
  252.    Result := rAudio_IsLoaded;
  253.    ReferenceCounter:=1;
  254. end;
  255.  
  256. end;
  257.  
  258. procedure rAudio_Unload();
  259. begin
  260.   if ReferenceCounter > 0 then dec(ReferenceCounter);
  261.   if ReferenceCounter > 0 then exit;
  262.   if rAudio_IsLoaded then
  263.   begin
  264.     DynLibs.UnloadLibrary(rAudio_Handle);
  265.     rAudio_Handle:=DynLibs.NilHandle;
  266.   end;
  267. end;
  268.  
  269. end.
  270.  
  271.  

Guva

  • Full Member
  • ***
  • Posts: 117
Re: Future Composer Player
« Reply #6 on: November 25, 2024, 07:41:30 am »
C language wrapper library for Future Composer audio decoding
https://github.com/mschwendt/libfc14audiodecoder

Code: Pascal  [Select][+][-]
  1. unit fc_lib;
  2.  
  3. {$mode delphi}{$H+}
  4. {$PACKRECORDS C}
  5.  
  6. interface
  7.  
  8. uses
  9.   DynLibs, SysUtils, CTypes;
  10.  
  11. const
  12.   {$IFDEF windows}
  13.     FCLIB = 'fc14audiodecoder.dll';
  14.   {$ENDIF}
  15.   {$IFDEF linux}
  16.     FCLIB = 'libfc14audiodecoder.so.1.0.0';
  17.   {$ENDIF}
  18.  
  19. type
  20.  
  21.   pfc14 = Pointer;
  22.  
  23. var
  24.   fc14dec_new: function: pfc14; cdecl;
  25.   fc14dec_delete: procedure(decoder: pfc14); cdecl;
  26.   fc14dec_detect: function(decoder: pfc14; buffer: Pointer; length: LongInt): Integer; cdecl;
  27.  
  28.   fc14dec_init: function(decoder: pfc14; buffer: Pointer; length: LongInt): Integer; cdecl;
  29.  
  30.   fc14dec_restart: procedure(decoder: pfc14); cdecl;
  31.   fc14dec_mixer_init: procedure(decoder: pfc14; frequency: Integer; precision: Integer; channels: Integer; zero: Integer); cdecl;
  32.   fc14dec_song_end: function(decoder: pfc14): Integer; cdecl;
  33.   fc14dec_duration: function(decoder: pfc14): Cardinal; cdecl;
  34.   fc14dec_seek: procedure(decoder: pfc14; ms: LongInt); cdecl;
  35.   fc14dec_format_name: function(decoder: pfc14): PChar; cdecl;
  36.   fc14dec_buffer_fill: function(decoder: pfc14; buffer: Pointer; length: LongInt): LongInt; cdecl;
  37.  
  38.   fc14_Handle: TLibHandle = dynlibs.NilHandle;
  39.   ReferenceCounter: cardinal = 0;
  40.  
  41.   function fc14_IsLoaded: Boolean; inline;
  42.   function fc14_Load(const libfilename: string): Boolean;
  43.   procedure fc14_Unload();
  44.  
  45. implementation
  46.  
  47. function fc14_IsLoaded: Boolean;
  48. begin
  49.   Result := (fc14_Handle <> dynlibs.NilHandle);
  50. end;
  51.  
  52. function fc14_Load(const libfilename: string): Boolean;
  53. var
  54. thelib: string;
  55. begin
  56.   Result := False;
  57.   if fc14_Handle<>0 then
  58.   begin
  59.     Inc(ReferenceCounter);
  60.     result:=true {is it already there ?}
  61.   end else
  62.   begin
  63.   {go & load the library}
  64.    if Length(libfilename) = 0 then thelib := FCLIB else
  65.    thelib := libfilename;
  66.     fc14_Handle:=DynLibs.LoadLibrary(thelib); // obtain the handle we want
  67.    if fc14_Handle <> DynLibs.NilHandle then
  68.   begin {now we tie the functions to the VARs from above}
  69.     (fc14dec_new):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_new'));
  70.     (fc14dec_delete):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_delete'));
  71.     (fc14dec_detect):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_detect'));
  72.     (fc14dec_init):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_init'));
  73.     (fc14dec_restart):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_restart'));
  74.     (fc14dec_mixer_init):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_mixer_init'));
  75.     (fc14dec_song_end):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_song_end'));
  76.     (fc14dec_duration):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_duration'));
  77.     (fc14dec_seek):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_seek'));
  78.     (fc14dec_format_name):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_format_name'));
  79.     (fc14dec_buffer_fill):=DynLibs.GetProcedureAddress(fc14_Handle,PChar('fc14dec_buffer_fill'));
  80.  
  81.  end;
  82.    Result := fc14_IsLoaded;
  83.    ReferenceCounter:=1;
  84. end;
  85.  
  86. end;
  87.  
  88. procedure fc14_Unload();
  89. begin
  90.   if ReferenceCounter > 0 then
  91.     dec(ReferenceCounter);
  92.   if ReferenceCounter > 0 then
  93.     exit;
  94.   if fc14_IsLoaded then
  95.   begin
  96.     DynLibs.UnloadLibrary(fc14_Handle);
  97.     fc14_Handle:=DynLibs.NilHandle;
  98.   end;
  99. end;
  100.  
  101.  
  102. end.
  103.  
« Last Edit: November 25, 2024, 07:46:56 am by Guva »

TRon

  • Hero Member
  • *****
  • Posts: 3650
Re: Future Composer Player
« Reply #7 on: November 26, 2024, 03:28:09 am »
I will make my contribution
Thank you very much for the raudio example Guva !

Quote
However, there is a problem . For some reason it only works in {$mode delphi}
Tested with your fc library I did not had a problem (but I did not test your raudio headers).

I took a stab at it based on your example, perhaps that works for you in Delphi mode as well.

Linux/Bash required.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Guva

  • Full Member
  • ***
  • Posts: 117
Re: Future Composer Player
« Reply #8 on: November 26, 2024, 05:06:28 am »
I will make my contribution
Thank you very much for the raudio example Guva !

Quote
However, there is a problem . For some reason it only works in {$mode delphi}
Tested with your fc library I did not had a problem (but I did not test your raudio headers).

I took a stab at it based on your example, perhaps that works for you in Delphi mode as well.

Linux/Bash required.
Oh yes thank you!
the problem was with my binding for Future Composer

Roland57

  • Sr. Member
  • ****
  • Posts: 475
    • msegui.net
Re: Future Composer Player
« Reply #9 on: November 26, 2024, 07:17:40 am »
I took a stab at it based on your example, perhaps that works for you in Delphi mode as well.

Linux/Bash required.

Very nice bash scripts! This one works perfectly here (Linux Mageia). The one that you posted before works also, excepted that I don't have libao installed, and my package manager offers only the 32-bit version.
My projects are on Gitlab and on Codeberg.

TRon

  • Hero Member
  • *****
  • Posts: 3650
Re: Future Composer Player
« Reply #10 on: November 26, 2024, 01:14:49 pm »
Very nice bash scripts!
Thank you Roland57. I try to keep things simple.

Quote
This one works perfectly here (Linux Mageia).
Good to know. Thank you for the feedback.

Quote
The one that you posted before works also, excepted that I don't have libao installed, and my package manager offers only the 32-bit version.
Ah, yes. In order to keep the scripts simple there is some basic functionality that is missing such as the absence of sanity checks (my scripts usually have a tendency to keep on rollin' on)  :)

I tried to compile libao from source (not a problem) but ao seem to require a particular configuration depending on the individual audio-setup. I did not manage to find clear information/descriptions for that, so in the end abandoned that idea/approach.

It will take me some time (need to find a free spot) but if wanted it would be possible to rewrite the example to use sndio, openal portaudio and/or raudio instead (not to mention that hukka's code should be cleaned up and re-organized further in order to make it more manageable).
« Last Edit: November 26, 2024, 02:03:31 pm by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

TRon

  • Hero Member
  • *****
  • Posts: 3650
Re: Future Composer Player
« Reply #11 on: November 26, 2024, 02:27:01 pm »
Oh yes thank you!
Your welcome. Again thank you very much for the raudio example (I wasn't aware that existed).

Quote
the problem was with my binding for Future Composer
Glad that you were able to get it to work but a bit strange result. I literally replaced my example with your fc_lib unit and that seems to have worked for me in mode objfpc. Perhaps luck of the draw on my side ?

btw: I noticed that with some songs the sound seem to start in the middle of the first few frames, is that something related to raudio or the way that I use it ? (I did not had a close look at how raudio works and was already a bit confused by the different functions for audiostream and musicstream, as in I did not understood the difference).
« Last Edit: November 26, 2024, 02:32:51 pm by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Guva

  • Full Member
  • ***
  • Posts: 117
Re: Future Composer Player
« Reply #12 on: November 26, 2024, 04:38:32 pm »
Quote
btw: I noticed that with some songs the sound seem to start in the middle of the first few frames, is that something related to raudio or the way that I use it ? (I did not had a close look at how raudio works and was already a bit confused by the different functions for audiostream and musicstream, as in I did not understood the difference).

Mysticism. I also had it like this, for example, I compared the sound here  https://nostalgicplayer.dk/modules/format/futurecomposer14/1?pageRef=6 Axel F
if you put mono, then everything worked well. I already wanted to leave it.  but it started to work, I still don't understand why.  maybe it depends on the backend that use raylib, although everything works fine for libxmp.

Roland57

  • Sr. Member
  • ****
  • Posts: 475
    • msegui.net
Re: Future Composer Player
« Reply #13 on: November 26, 2024, 07:39:07 pm »
I tried to compile libao from source (not a problem) but ao seem to require a particular configuration depending on the individual audio-setup. I did not manage to find clear information/descriptions for that, so in the end abandoned that idea/approach.

I could compile libao. Now the example works, with an error message:

ERROR: Failed to load plugin /usr/local/lib/ao/plugins-4/libalsa.so => dlopen() failed

Maybe I did something wrong.

git clone https://github.com/xiph/libao.git
cd libao
sh autogen.sh
autoupdate
./configure
make
sudo make install
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/local/lib/ao/plugins-4
export LD_LIBRARY_PATH
./fc_play "music/Delta.fc"


It will take me some time (need to find a free spot) but if wanted it would be possible to rewrite the example to use sndio, openal portaudio and/or raudio instead (not to mention that hukka's code should be cleaned up and re-organized further in order to make it more manageable).

Could be interesting indeed.  :)
My projects are on Gitlab and on Codeberg.

TRon

  • Hero Member
  • *****
  • Posts: 3650
Re: Future Composer Player
« Reply #14 on: November 26, 2024, 08:22:55 pm »
Maybe I did something wrong.
The instructions are ok. Do you have libasound installed ?

If you need to investigate more, then it is possible to do so with strace, e.g. strace ./fc_play "music/Delta.fc" but be advised that it produces a lot of technical info. The idea is to filter and locate the paths it tries to open libasound, path being, fc_play -> libao -> plugin libalsa -> system installed libasound -> others ?

Along that path it seems to fail for you somewhere (but I do not have any idea what and where).

Quote
Could be interesting indeed.  :)
I see what I can do. It is easy enough to do but I am swamped (and I do not want to start ww3@home  :D )

PS: the dependencies (ldd) for libao's libalsa plugin (for me) are:
Code: [Select]
linux-vdso.so.1 (0x00007fff86298000)
libasound.so.2 => /lib/x86_64-linux-gnu/libasound.so.2 (0x00007f38bdc75000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f38bda94000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f38bd9b5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f38bdda7000)


EDIT:

Because raylib seems to be working for you, I've attached a version using raudio for hukka's native player.
« Last Edit: November 28, 2024, 03:10:21 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

 

TinyPortal © 2005-2018