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