sfplay.pp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. program sfplay;
  2. {$mode objfpc}
  3. {$h+}
  4. uses sndfile, baseunix;
  5. Const
  6. BUFFERLEN = 1024;
  7. Const
  8. { Values obtained from a C program - These are complex (!) C macros }
  9. SNDCTL_DSP_STEREO = -1073459197;
  10. SNDCTL_DSP_RESET = 20480;
  11. SNDCTL_DSP_SYNC = 20481;
  12. SOUND_PCM_WRITE_BITS = -1073459195;
  13. SOUND_PCM_WRITE_CHANNELS = -1073459194;
  14. SOUND_PCM_WRITE_RATE = -1073459198;
  15. ResourceString
  16. SPlaying = 'Playing : ';
  17. SErrChannels = 'Error : Number of channels not supported: ';
  18. SErrOpeningDevice = 'Could not open sound device';
  19. SErrSettingStereo = 'Could not set stereo';
  20. SErrResettingDevice = 'Could not reset DSP device';
  21. SErrSetWriteBits = 'Could not set write bits to 16';
  22. SErrSetChannels = 'Could not set channels';
  23. SErrSetSampleRate = 'Could not set sync mode';
  24. SErrSetSyncMode = 'Could not set sync mode';
  25. Procedure PlayError(Msg : String);
  26. begin
  27. Writeln(stderr,Msg);
  28. Halt(1);
  29. end;
  30. Function OpenDSPDevice(Channels,Samplerate : LongInt) : LongInt; forward;
  31. procedure PlayFile(FileName : String);
  32. var
  33. Buffer: Array[0..BUFFERLEN-1] of word;
  34. SoundFile: PSndFile;
  35. Info: TSF_INFO;
  36. k, m, AudioDevice, readcount: Longint;
  37. ScaleData: Boolean;
  38. begin
  39. Writeln(SPlaying,FileName);
  40. SoundFile:=sf_open(PAnsiChar(FileName), SFM_READ, @Info);
  41. If (SoundFile=Nil) then
  42. begin
  43. sf_perror(Nil);
  44. exit;
  45. end;
  46. If not (Info.Channels in [1,2]) then
  47. PlayError(SerrChannels);
  48. AudioDevice:=OpenDSPDevice(Info.channels, Info.samplerate);
  49. ScaleData:=(Info.samplerate < 16);
  50. readcount:=sf_read_short(SoundFile,@Buffer,BUFFERLEN);
  51. While ReadCount<>0 do
  52. begin
  53. If ScaleData then
  54. For m:=0 to BufferLen-1 do
  55. Buffer[m]:=buffer[m] * 256;
  56. FpWrite(AudioDevice, buffer, readcount * sizeof (word)) ;
  57. readcount:=sf_read_short(SoundFile,@Buffer,BUFFERLEN);
  58. end;
  59. sf_close (Soundfile) ;
  60. FpClose(AudioDevice) ;
  61. end;
  62. Function OpenDSPDevice (channels,SampleRate : LongInt) : Longint;
  63. var
  64. fd, stereo, temp, error : longint ;
  65. begin
  66. fd:=fpOpen('/dev/dsp',O_WRONLY,0);
  67. if fd<0 then
  68. PlayError(SErrOpeningDevice);
  69. Stereo:=0;
  70. if Not (FpIOCtl(fd, SNDCTL_DSP_STEREO , @stereo) <> -1) then
  71. PlayError(SErrSettingStereo);
  72. if Not (FpIOCtl(fd, SNDCTL_DSP_RESET, Nil) <> -1) then
  73. PlayError(SErrResettingDevice);
  74. temp := 16 ;
  75. If not (FpIOCtl(fd, SOUND_PCM_WRITE_BITS, @temp) <> -1) then
  76. PlayError(SErrSetWriteBits);
  77. If not (FpIOCtl(fd, SOUND_PCM_WRITE_CHANNELS, @channels) <> -1) then
  78. PlayError(SErrSetChannels);
  79. If Not (FpIOCtl(fd, SOUND_PCM_WRITE_RATE, @SampleRate) <> -1) then
  80. PlayError(SErrSetSampleRate);
  81. If not (FpIOCtl(fd, SNDCTL_DSP_SYNC, Nil) <> -1) then
  82. PlayError(SErrSetSyncMode);
  83. OpenDSPDevice:=Fd;
  84. end;
  85. Var
  86. I : Integer;
  87. begin
  88. For I:=1 to ParamCount do
  89. PlayFile(Paramstr(i));
  90. end.