35
35
#include <limits.h>
36
36
#include <math.h>
37
37
#include <pthread.h>
38
+ #include <stdio.h>
39
+ #include <unistd.h>
40
+ #include <stdlib.h>
41
+ #include <sys/types.h>
42
+ #include <sys/stat.h>
43
+ #include <sys/ioctl.h>
44
+ #include <fcntl.h>
38
45
39
46
#if USE_ALSA
40
47
#include <alsa/asoundlib.h>
@@ -89,11 +96,11 @@ static void * ptt_thread (void *arg)
89
96
snd_pcm_t * handle ;
90
97
int err ;
91
98
92
- err = snd_pcm_open (& handle , save_audio_config_p -> adev [a ].adevice_out , SND_PCM_STREAM_PLAYBACK , 0 );
99
+ err = snd_pcm_open (& handle , save_audio_config_p -> adev [a ].adevice_out , SND_PCM_STREAM_PLAYBACK , 0 );
93
100
if (err == 0 ) {
94
101
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE ;
95
102
96
- err = snd_pcm_set_params (handle , format , SND_PCM_ACCESS_RW_INTERLEAVED ,
103
+ err = snd_pcm_set_params (handle , format , SND_PCM_ACCESS_RW_INTERLEAVED ,
97
104
save_audio_config_p -> adev [a ].num_channels ,
98
105
save_audio_config_p -> adev [a ].samples_per_sec , 1 , 500000 );
99
106
if (err == 0 ) {
@@ -136,8 +143,8 @@ static void * ptt_thread (void *arg)
136
143
}
137
144
}
138
145
139
- if (ptt_state == PTT_AUDIO_STATE_START ) {
140
- snd_pcm_writei (handle , pnData , nSamples );
146
+ if (ptt_state == PTT_AUDIO_STATE_START ) {
147
+ snd_pcm_writei (handle , pnData , nSamples );
141
148
}
142
149
else if (ptt_state == PTT_AUDIO_STATE_CLOSE ) {
143
150
snd_pcm_drop (handle );
@@ -147,15 +154,97 @@ static void * ptt_thread (void *arg)
147
154
}
148
155
149
156
free (pnData );
150
- }
157
+ } else {
158
+ dw_printf ("Failed to configure ALSA device. PTT tone will not be enabled.\n" );
159
+ }
151
160
snd_pcm_close (handle );
152
- }
161
+ } else {
162
+ dw_printf ("Failed to open ALSA device. PTT tone will not be enabled.\n" );
163
+ }
153
164
#else
154
165
int oss_audio_device_fd ;
155
166
156
167
oss_audio_device_fd = open (save_audio_config_p -> adev [a ].adevice_out , O_WRONLY );
157
- if (oss_audio_device_fd != -1 ) {
168
+ if (oss_audio_device_fd >= 0 ) {
169
+ int devcaps ;
170
+ int num_channels ;
171
+ int samples_per_sec ;
172
+ int bits_per_sample ;
173
+ int err ;
174
+
175
+ num_channels = save_audio_config_p -> adev [a ].num_channels ;
176
+ err = ioctl (oss_audio_device_fd , SNDCTL_DSP_CHANNELS , & num_channels );
177
+
178
+ if (err != -1 ) {
179
+ samples_per_sec = save_audio_config_p -> adev [a ].samples_per_sec ;
180
+ err = ioctl (oss_audio_device_fd , SNDCTL_DSP_SPEED , & samples_per_sec );
181
+ }
182
+
183
+ if (err != -1 ) {
184
+ bits_per_sample = save_audio_config_p -> adev [a ].bits_per_sample ;
185
+ err = ioctl (oss_audio_device_fd , SNDCTL_DSP_SETFMT , & bits_per_sample );
186
+ }
187
+
188
+ if (err != -1 ) {
189
+ err = ioctl (oss_audio_device_fd , SNDCTL_DSP_GETCAPS , & devcaps );
190
+ }
191
+
192
+ if (err != -1 ) {
193
+ short * pnData ;
194
+ short sample ;
195
+ int nBufferLength ;
196
+ int nSamples ;
197
+ int written ;
198
+ int i ;
199
+ int j ;
200
+
201
+ nSamples = samples_per_sec / 5 ;
202
+ nBufferLength = num_channels * nSamples * sizeof (short );
203
+ pnData = (short * )malloc (nBufferLength );
204
+
205
+ for (i = 0 ; i < nSamples ; i ++ ) {
206
+ sample = (short )( (double )SHRT_MAX * sin ( ( (double )i * freq / (double )samples_per_sec ) * 2.0 * M_PI ) );
207
+
208
+ for (j = 0 ; j < num_channels ; j ++ ) {
209
+ if (channel == ADEVFIRSTCHAN ( a ) + j ) {
210
+ pnData [i * num_channels + j ] = sample ;
211
+ } else {
212
+ pnData [i * num_channels + j ] = 0 ;
213
+ }
214
+ }
215
+ }
216
+
217
+ while (1 ) {
218
+ pthread_mutex_lock (& save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_mutex );
219
+ ptt_audio_state_t ptt_state = save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_state ;
220
+ pthread_mutex_unlock (& save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_mutex );
221
+
222
+ if (ptt_state == PTT_AUDIO_STATE_STOP ) {
223
+ ioctl (oss_audio_device_fd , SNDCTL_DSP_RESET , NULL );
224
+
225
+ pthread_mutex_lock (& save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_mutex );
226
+ pthread_cond_wait (& save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_condition , & save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_mutex );
227
+ ptt_state = save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_state ;
228
+ pthread_mutex_unlock (& save_audio_config_p -> achan [ch ].octrl [OCTYPE_PTT ].ptt_mutex );
229
+ }
230
+
231
+ if (ptt_state == PTT_AUDIO_STATE_START ) {
232
+ written = write (oss_audio_device_fd , pnData , nBufferLength );
233
+ }
234
+ else if (ptt_state == PTT_AUDIO_STATE_CLOSE ) {
235
+ ioctl (oss_audio_device_fd , SNDCTL_DSP_RESET , NULL );
236
+
237
+ break ;
238
+ }
239
+ }
158
240
241
+ free (pnData );
242
+ } else {
243
+ dw_printf ("Failed to configure OSS device. PTT tone will not be enabled.\n" );
244
+ }
245
+ close (oss_audio_device_fd );
246
+ } else {
247
+ dw_printf ("Failed to open OSS device. PTT tone will not be enabled.\n" );
159
248
}
160
249
#endif
161
250
}
0 commit comments