1 #include <unistd.h>
2 #include <fcntl.h>
3 #include <sys/ioctl.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/soundcard.h>
7 #include "ctronome.h"
8
9 static int dsp_8bit_unsigned_format = AFMT_U8; /* 0x00000008 unsigned 8 bit*/
10 static int dsp_16bit_signed_format = AFMT_S16_LE; /* 0x00000010 signed 16 bit little endianess*/
11
12 static int debug_dsp_speed, debug_dsp_channels, debug_dsp_depth, supported_dsp_formats;
13
dsp_init(byte * dsp_dev,word bitspersample,word channels,dword samplerate)14 int dsp_init(byte *dsp_dev,word bitspersample, word channels, dword samplerate){
15 int dsp_handle;
16
17 dsp_format = 0;
18 if (debug) printf ("debug: dsp.c: bitspersample: >%d<\n",bitspersample);
19 /* check parameters */
20 if (bitspersample == 8)
21 dsp_format = dsp_8bit_unsigned_format;
22 if (bitspersample == 16){
23 dsp_format = dsp_16bit_signed_format;
24 }
25
26 if(!(dsp_format)){
27 printf ("FATAL: only 8 and 16 bits per sample are supported. (got: %d\n",bitspersample);
28 exit (1);
29 }
30 if (debug) printf ("debug: dsp.c: wanted AFMT: >%d<\n",dsp_format);
31
32 if ((channels < 1) && (channels > 2)){
33 printf ("FATAL: number of channels must be 1 (mono) or 2 (stereo) (got: %d\n",channels);
34 exit (1);
35 }
36 dsp_channels = channels;
37
38 if ((samplerate < 8000) && (samplerate > 96000)){
39 printf ("FATAL: samplerate must be between 8000 and 96000 (got: %d\n",samplerate);
40 exit (1);
41 }
42 dsp_speed = samplerate;
43
44 /* Initialise dsp_dev */
45 if (debug) printf ("debug: opening dsp '%s'\n",dsp_dev);
46 if ((dsp_handle = open (dsp_dev, O_WRONLY)) == -1){
47 printf ("FATAL: cannot open dsp device %s\n",dsp_dev);
48 perror(dsp_dev);
49 exit (1);
50 }
51 if (debug) printf ("debug: dsp device %s opened successfully\n",dsp_dev);
52
53 if (debug){
54 if (ioctl(dsp_handle, SNDCTL_DSP_GETFMTS, &supported_dsp_formats) == -1){
55 printf ("FATAL: unable to get supported formats for %s\n",dsp_dev);
56 perror("SNDCTL_DSP_GETFMT");
57 exit(1);
58 }
59 printf("debug: supported dsp formats: '%d'\n",supported_dsp_formats);
60 }
61
62 if (debug) printf ("debug: dsp: set format: SNDCTL_DSP_SETFMT(%d)\n",dsp_format);
63 if ((ioctl (dsp_handle, SNDCTL_DSP_SETFMT, &dsp_format)) == -1){
64 printf ("FATAL: unable to set output format for %s\n",dsp_dev);
65 perror("SNDCTL_DSP_SETFMT");
66 exit(1);
67 }
68
69 if (debug) printf ("debug: dsp: set format returned '%d'\n",dsp_format);
70 if ((bitspersample == 8) && (dsp_format != dsp_8bit_unsigned_format)){
71 printf("FATAL: your dsp device does not seem to support unsigned 8 bit (AFMT_8U) format\n");
72 exit(1);
73 }
74
75 if ((bitspersample == 16) && (dsp_format != dsp_16bit_signed_format)){
76 printf("FATAL: your dsp device does not seem to support signed 16 bit (AFMT_S16_LE) format\n");
77 exit(1);
78 }
79
80 /* Set dsp channels */
81 if (debug) printf ("debug: dsp: set up channels: SNDCTL_DSP_CHANNELS(%d)\n",dsp_channels);
82 /* ioctl (dsp_handle, SNDCTL_DSP_CHANNELS, &dsp_channels); */
83 if (ioctl (dsp_handle, SNDCTL_DSP_CHANNELS, &dsp_channels) == -1){
84 printf ("FATAL: unable to set no. of channels for %s\n",dsp_dev);
85 perror("SNDCTL_DSP_CHANNELS");
86 exit(1);
87 }
88
89 if (debug) printf ("debug: dsp: set no. of channels returned '%d'\n",dsp_channels);
90 if (dsp_channels != channels){
91 printf ("FATAL: your wav has %d channels, while your DSP only supports %d channels.\n",channels,dsp_channels);
92 exit(1);
93 }
94
95 /* Set the DSP rate (in Hz) */
96 if (debug) printf ("debug: dsp: set up speed (Hz): SNDCTL_DSP_SPEED(%d)\n",dsp_speed);
97 if (ioctl (dsp_handle, SNDCTL_DSP_SPEED, &dsp_speed) == -1){
98 printf ("FATAL: unable to set DSP speed for %s\n",dsp_dev);
99 perror("SNDCTL_DSP_SPEED");
100 exit(1);
101 }
102
103 if (debug) printf ("debug: dsp: set speed returned '%d'\n",dsp_speed);
104 if (debug && (dsp_speed != samplerate)){
105 printf ("debug: dsp: wav samplerate and dsp samplerate differs, will sound funny\n");
106 }
107
108 return(dsp_handle);
109 }
110
dsp_close(byte dsp_handle)111 void dsp_close (byte dsp_handle)
112 {
113 close(dsp_handle);
114 }
115
dsp_write(byte dsp_handle,byte * from,dword count)116 void dsp_write (byte dsp_handle,byte *from,dword count){
117 dword bytes_written;
118 bytes_written = write (dsp_handle,from,count);
119 if (bytes_written < count){
120 printf ("FATAL: tried to write %d bytes to dsp device,\n\
121 only %d is written\n",count,bytes_written);
122 exit(1);
123 }
124 return;
125 }
126
127