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