Recent

Author Topic: YM Player  (Read 812 times)

Gigatron

  • Full Member
  • ***
  • Posts: 161
  • Amiga Rulez !!
YM Player
« on: September 25, 2024, 10:26:41 pm »
Hi,
I am working on the st Sound ym player; ym mean a module format from Arnaud Carré alias Leonard Oxygen
http://leonard.oxg.free.fr/

Here is the beta stage on this nice player; the compiler option is set to OS to Win32 and CPU I386;
The library YM2149SSND.dll is for 32bit not for X64 .. not working when compiling for X64 on visual studio ;

I certainly made mistakes in the code, but it's a beta version and the modules works :)
ftp modland ym database : https://modland.com/pub/modules/YM/

All units and module (tcb.ym) and library are here :)

main unit :
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. //{$PACKRECORDS C}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, windows,
  10.   mmsystem, ym_player ;
  11.  
  12. const
  13.   REPLAY_RATE = 44100;
  14.   Channels = 1;
  15.   ym_File = 'tcb.ym';
  16.   REPLAY_DEPTH  = 16;
  17.   REPLAY_SAMPLELEN = REPLAY_DEPTH div 8;
  18.   SampleRate = 44100; // number of samples per second
  19.   BufSize = 65536*2 ; //   multiple of 2
  20.   BufferCount = 4;
  21.  
  22.  type
  23.  TYM_MusicInfo = record
  24.     pSongName: PAnsiChar;
  25.     pSongAuthor: PAnsiChar;
  26.     pSongComment: PAnsiChar;
  27.     pSongType: PAnsiChar;
  28.     pSongPlayer: PAnsiChar;
  29.     musicTimeInSec: Integer;
  30.     musicTimeInMs: Integer;
  31.   end;
  32.  
  33.   { TForm1 }
  34.  
  35.   TForm1 = class(TForm)
  36.     Timer1: TTimer;
  37.     procedure FormCreate(Sender: TObject);
  38.  
  39.     procedure Timer1Timer(Sender: TObject);
  40.   private
  41.      buffers: array[0..BufferCount-1] of array[0..BufSize-1] of SmallInt;
  42.      waveHeaders: array[0..BufferCount-1] of TWaveHdr;
  43.      currentBuffer: Integer;
  44.   public
  45. end;
  46.  
  47. var
  48.   Form1: TForm1;
  49.   waveOut: HWAVEOUT;
  50.   waveHeader: TWaveHdr;
  51.   ym_pmus: PYM_Music ;
  52.   ym_mus : string;
  53.   ok_flag : boolean = true;
  54.  
  55. implementation
  56.  
  57. {$R *.lfm}
  58.  
  59. /// audio init et le reste !!
  60. procedure HandleError(const Str: PAnsiChar);
  61. begin
  62.   if Str <> nil then
  63.   begin
  64.     ShowMessage('Error: Wrong Format ? '+ Str);
  65.     Halt(1);
  66.   end;
  67. end;
  68.  
  69. procedure FillBuffer(bufferIndex: Integer);
  70. begin
  71.  
  72.     YM_ComputePCM(ym_pmus, @Form1.buffers[bufferIndex][0], BufSize  );
  73.      if Form1.buffers[bufferIndex][0] = 0 then
  74.   begin
  75.     ShowMessage('Attention : le buffer est vide');
  76.   end;
  77.   Form1.waveHeaders[bufferIndex].dwFlags := Form1.waveHeaders[bufferIndex].dwFlags and (not WHDR_DONE);
  78.  
  79. end;
  80.  
  81. function WaveOutCallback(hwo: HWAVEOUT; uMsg: UINT; dwInstance, dwParam1, dwParam2: DWORD_PTR): DWORD; stdcall;
  82. begin
  83.   if uMsg = WOM_DONE then
  84.   begin
  85.      FillBuffer(Form1.currentBuffer);
  86.     waveOutWrite(waveOut, @Form1.waveHeaders[Form1.currentBuffer], SizeOf(TWaveHdr));
  87.     Form1.currentBuffer := (Form1.currentBuffer + 1) mod BufferCount;
  88.   end;
  89.  
  90.   Result := 0;
  91. end;
  92.  
  93. procedure InitAudio;
  94. var
  95.   wFormat: TWaveFormatEx;
  96.   i: Integer;
  97. begin
  98.   SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_LOWEST);
  99.  
  100.   with wFormat do
  101.   begin
  102.  
  103.    wFormatTag := WAVE_FORMAT_PCM; // 1
  104.    nChannels := 1; // Mono
  105.    nSamplesPerSec := REPLAY_RATE; // 44100
  106.    wBitsPerSample := REPLAY_DEPTH; // 16 bits
  107.    nBlockAlign := nChannels * (wBitsPerSample div 8); // Taille echantillon
  108.    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
  109.    cbSize := 0;
  110.   end;
  111.  
  112.   if waveOutOpen(@waveOut, WAVE_MAPPER, @wFormat, QWORD(@WaveOutCallback), 0, CALLBACK_FUNCTION) <> MMSYSERR_NOERROR then
  113.    ShowMessage('Error: Audio initialization failed');
  114.  
  115.   // buffers
  116.   for i := 0 to BufferCount - 1 do
  117.   begin
  118.     ZeroMemory(@Form1.waveHeaders[i], SizeOf(TWaveHdr));
  119.      with Form1.waveHeaders[i] do
  120.     begin
  121.       lpData := @Form1.buffers[i][0];
  122.       dwBufferLength := BufSize * SizeOf(SmallInt);
  123.       dwFlags := 0 ;
  124.     end;
  125.      waveOutPrepareHeader(waveOut, @Form1.waveHeaders[i], SizeOf(TWaveHdr));
  126.   end;
  127.  
  128.    Form1.currentBuffer := 0;
  129. end;
  130.  
  131. { TForm1 }
  132.  
  133. procedure TForm1.FormCreate(Sender: TObject);
  134.  
  135.  begin
  136.     ym_mus :='tcb.ym';
  137.     InitAudio;
  138.     ym_pmus := YM_Init;
  139.  
  140.    if ym_pmus = nil then
  141.     ShowMessage('YM_Init failed');
  142.  
  143.    YM_LoadFile(ym_pmus, Pchar(ym_mus));
  144.  
  145.    if not YM_LoadFile(ym_pmus, Pchar(ym_mus)) then
  146.    begin
  147.      ShowMessage('YM file not Loaded');
  148.      HandleError(YM_GetLastError(ym_pmus));
  149.      Exit;
  150.    end;
  151.  
  152.    FillBuffer(0);
  153.    waveOutWrite(waveOut, @waveHeaders[0], SizeOf(TWaveHdr));
  154.    YM_Play(ym_pmus);   // on va dans l'espace :))
  155.  
  156.  end;
  157. // noting yet for the timer !!
  158. procedure TForm1.Timer1Timer(Sender: TObject);
  159. begin
  160.  
  161. end;
  162.  
  163. end.
  164.  
  165.  

ym_player unit

 
Code: Pascal  [Select][+][-]
  1. // Based on c source from Arnaud Carré alias Leonard Oxygene stsoundLibrary 1.43
  2. // Credits : To do ..........
  3. // Pascal adaptation by Gigatron
  4. unit ym_player;
  5.  
  6. {$mode objfpc}{$H+}
  7.  
  8. interface
  9.  
  10. type
  11.   PYM_Music = Pointer;
  12.  
  13.  
  14.   const
  15.   YM  = 1;
  16.   SND = 0;
  17.  
  18.     type
  19.     PYMMusicInfo = record
  20.       pSongName: PChar;
  21.       pSongAuthor: PChar;
  22.       pSongComment: PChar;
  23.       pSongType: PChar;
  24.       pSongPlayer: PChar;
  25.       musicTimeInSec: Integer;
  26.       musicTimeInMs: Integer;
  27.     end;
  28.  
  29.  
  30.   const
  31.     YMFALSE = 0;
  32.     YMTRUE = not YMFALSE;
  33.  
  34. function YM_Init: PYM_Music; cdecl; external 'YM2149SSND.dll';
  35. procedure YM_Destroy(pMusic: PYM_Music); cdecl; external 'YM2149SSND.dll';
  36. function YM_LoadFile(pMusic: PYM_Music; mus: PAnsiChar): Boolean; cdecl; external 'YM2149SSND.dll';
  37. function YM_LoadFromMemory(pMusic: PYM_Music; pBlock: Pointer; size: Integer): Boolean; cdecl; external 'YM2149SSND.dll';
  38. procedure YM_Play(pMusic: PYM_Music); cdecl; external 'YM2149SSND.dll';
  39. function YM_ComputePCM(pMusic: PYM_Music; pBuffer: Pointer; nbSample: Integer): Boolean; cdecl; external 'YM2149SSND.dll';
  40. procedure YM_Information(pMusic: PYM_Music; Info: PYMMusicInfo); cdecl; external 'YM2149SSND.dll';
  41.  
  42. procedure YM_LowpassFilter(pMusic: PYM_Music; bActive: Boolean); cdecl; external 'YM2149SSND.dll';
  43. procedure YM_SetLoopMode(pMusic: PYM_Music; bLoop: Boolean); cdecl; external 'YM2149SSND.dll';
  44. function  YM_GetLastError(pMusic: PYM_Music): PAnsiChar; cdecl; external 'YM2149SSND.dll';
  45. function  YM_GetRegister(pMusic: PYM_Music; reg: Integer): Integer; cdecl; external 'YM2149SSND.dll';
  46. procedure YM_Pause(pMusic: PYM_Music); cdecl; external 'YM2149SSND.dll';
  47. procedure YM_Stop(pMusic: PYM_Music); cdecl; external 'YM2149SSND.dll';
  48. function  YM_IsOver(pMusic: PYM_Music): Boolean; cdecl; external 'YM2149SSND.dll';
  49. procedure YM_Restart(pMusic: PYM_Music); cdecl; external 'YM2149SSND.dll';
  50. function  YM_IsSeekable(pMusic: PYM_Music): Boolean; cdecl; external 'YM2149SSND.dll';
  51. function  YM_GetPosition(pMusic: PYM_Music): LongInt; cdecl; external 'YM2149SSND.dll';
  52. procedure YM_MusicSeek(pMusic: PYM_Music; timeInMs: LongInt); cdecl; external 'YM2149SSND.dll';
  53.  
  54.  
  55. implementation
  56.  
  57. end.
  58.  
  59.  


 
« Last Edit: September 25, 2024, 10:32:37 pm by Gigatron »
Sub Quantum Technology ! Gigatron 68000 Colmar France;

TRon

  • Hero Member
  • *****
  • Posts: 3744
Re: YM Player
« Reply #1 on: December 03, 2024, 02:32:16 am »
🐧 For the intuxicated folks 🐧
I do not have to remember anything anymore thanks to total-recall.

 

TinyPortal © 2005-2018