~ubuntu-branches/ubuntu/vivid/oss4/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/gcc-4.6.patch/cmd/ossphone/ossphone.c

  • Committer: Package Import Robot
  • Author(s): Sebastien NOEL
  • Date: 2012-11-19 11:47:24 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20121119114724-svu8mq7x3pk64nez
Tags: 4.2-build2007-1
* New upstream release.
* Acknowledge NMU, thanks Michael Gilbert.
* Add debian/patches/110_ld-as-needed.patch: Rearrange order of linker
  arguments to fix building with "ld --as-needed" (closes: #630737).
* Add missing dependency on dpkg-dev to oss4-dkms and oss4-source
  (closes: #687086).
* Fix typo in the changelog (closes: #628876, #675933)
* Add debian/patches/002_fix-linux-oss_native_word.patch (closes: #693657).
  Thanks to Ben Hutchings.
* Add debian/patches/003_linux-error-logging-fixes.patch (closes: #693657).
  Thanks to Ben Hutchings.
* check for /lib/modules/${kernelver}/build in addition of
  /lib/modules/${kernelver}/source (closes: #587191).
* oss4-dkms.dkms.in: fix 'CLEAN' rules (closes: #653374).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Purpose: Utility to make phone calls using Open Sound System modem support.
3
 
 */
4
 
 
5
 
/*
6
 
 *
7
 
 * This file is part of Open Sound System.
8
 
 *
9
 
 * Copyright (C) 4Front Technologies 1996-2008.
10
 
 *
11
 
 * This this source file is released under GPL v2 license (no other versions).
12
 
 * See the COPYING file included in the main directory of this source
13
 
 * distribution for the license terms and conditions.
14
 
 *
15
 
 */
16
 
 
17
 
#include <stdio.h>
18
 
#include <stdlib.h>
19
 
#include <string.h>
20
 
#include <assert.h>
21
 
#include <stdint.h>
22
 
#include <unistd.h>
23
 
#include <signal.h>
24
 
#include <ctype.h>
25
 
#include <math.h>
26
 
#include <sys/types.h>
27
 
#include <sys/stat.h>
28
 
#include <fcntl.h>
29
 
#include <sys/ioctl.h>
30
 
#include <sys/select.h>
31
 
#include <soundcard.h>
32
 
 
33
 
char *cmdname=NULL;
34
 
 
35
 
int modem_in_fd = -1;
36
 
int modem_out_fd = -1;
37
 
int dev_dsp_fd = -1;
38
 
 
39
 
char *dspdev_name = "/dev/dsp"; /* Local audio device (headset) */
40
 
int srate = 8000;
41
 
double digit_duration = 0.2;
42
 
double silence_duration = 0.1;
43
 
 
44
 
/*
45
 
 * http://en.wikipedia.org/wiki/DTMF#Keypad
46
 
 */
47
 
 
48
 
const double dtmf_keypad_row[] = { 697.0,  770.0,  852.0,  941.0  };
49
 
const double dtmf_keypad_col[] = { 1209.0, 1336.0, 1477.0, 1633.0 };
50
 
const char *dtmf_keypad_keys = "123A456B789C*0#D";
51
 
 
52
 
static void
53
 
modem_write(int fd, const void *buf, size_t count)
54
 
{
55
 
        if (write(fd, buf, count) != count)
56
 
        {
57
 
                perror("Modem write");
58
 
                exit(1);
59
 
        }
60
 
}
61
 
 
62
 
static void
63
 
modem_read(int fd, void *buf, size_t count)
64
 
{
65
 
        if (read(fd, buf, count) != count)
66
 
        {
67
 
                perror("Modem read");
68
 
                exit(1);
69
 
        }
70
 
}
71
 
 
72
 
static int
73
 
dtmf_fill_digit(uint16_t *buf, size_t buf_len, int digit)
74
 
{
75
 
  const double A = 65536.0 / 8.0;
76
 
  const double pi = 3.14159265358979323846;
77
 
 
78
 
  const char *keypad_digit;
79
 
  double w1, w2;
80
 
  double t, sample_duration;
81
 
  size_t i, pos;
82
 
 
83
 
  keypad_digit = strchr(dtmf_keypad_keys, toupper(digit));
84
 
 
85
 
  if (keypad_digit == NULL)
86
 
      return -1;
87
 
 
88
 
  pos = (int)(keypad_digit - dtmf_keypad_keys);
89
 
 
90
 
  /* compute angular frequencies */
91
 
  w1 = 2.0*pi*dtmf_keypad_row[pos / 4];
92
 
  w2 = 2.0*pi*dtmf_keypad_col[pos % 4];
93
 
 
94
 
  t = 0.0;
95
 
  sample_duration = 1.0 / (double)srate;
96
 
 
97
 
  for (i = 0; i < buf_len; i++)
98
 
     {
99
 
       buf[i] = (uint16_t)(A + A*sin(w1*t) + A + A*sin(w2*t));
100
 
       t += sample_duration;
101
 
     }
102
 
  
103
 
  return 0;
104
 
}
105
 
 
106
 
static void
107
 
dtmf_fill_silence(uint16_t *buf, size_t buf_len)
108
 
{
109
 
  const uint16_t A = (uint16_t)(65536.0 / 4.0);
110
 
  size_t i;
111
 
 
112
 
  for (i = 0; i < buf_len; i++)
113
 
     {
114
 
       buf[i] = A;
115
 
     }
116
 
}
117
 
 
118
 
static double
119
 
evaluate_dc_level(uint16_t *buf, size_t buf_len)
120
 
{
121
 
  double sum = 0.0;
122
 
  size_t i;
123
 
 
124
 
  for (i = 0; i < buf_len; i++)
125
 
     {
126
 
       sum += ((double)buf[i]) / 65536.0;
127
 
     }
128
 
 
129
 
  return (sum / (double)buf_len);
130
 
}
131
 
 
132
 
static void
133
 
go_offhook()
134
 
{
135
 
  int offhook = 1;
136
 
 
137
 
  printf("Off-hook\n");
138
 
  ioctl (modem_out_fd, SNDCTL_DSP_MODEM_OFFHOOK, &offhook);
139
 
}
140
 
 
141
 
static int wait_dialtone()
142
 
{
143
 
  double dc_level = 0.0;
144
 
  const double min_dc_level = 0.2;
145
 
  
146
 
  uint16_t buf[4096];
147
 
 
148
 
  int retries = 0;
149
 
  const int max_retries = 10;
150
 
 
151
 
  printf("Waiting for dial tone...\n");
152
 
  while (dc_level < min_dc_level)
153
 
       {
154
 
         int dummy;
155
 
         modem_read(modem_in_fd, buf, sizeof(buf));
156
 
         dummy=write(dev_dsp_fd, buf, sizeof(buf));
157
 
 
158
 
         dc_level = evaluate_dc_level(buf, sizeof(buf)/sizeof(uint16_t));
159
 
 
160
 
         if (retries++ > max_retries)
161
 
           {
162
 
             return -1;
163
 
           }
164
 
       }
165
 
 
166
 
  return 0;
167
 
}
168
 
 
169
 
static void
170
 
dial_phone_number(const char *phone_number)
171
 
{
172
 
  size_t digit_len = (size_t)(digit_duration*srate);
173
 
  size_t silence_len = (size_t)(silence_duration*srate);
174
 
  size_t digit_size = digit_len * sizeof(uint16_t);
175
 
  size_t silence_size = silence_len * sizeof(uint16_t);
176
 
  
177
 
  uint16_t *digit = (uint16_t *)malloc(digit_size);
178
 
  uint16_t *silence = (uint16_t *)malloc(silence_size);
179
 
  uint16_t *buf = (uint16_t *)malloc(silence_size);
180
 
 
181
 
  dtmf_fill_silence (silence, silence_len);
182
 
 
183
 
  printf("Dialing... ");
184
 
  fflush(stdout);
185
 
 
186
 
  while (*phone_number != '\0')
187
 
       {
188
 
         if (dtmf_fill_digit (digit, digit_len, *phone_number) >= 0)
189
 
           {
190
 
             int dummy;
191
 
 
192
 
             printf("%c", *phone_number);
193
 
             fflush(stdout);
194
 
 
195
 
             modem_write (modem_out_fd, digit, digit_size);
196
 
             modem_read (modem_in_fd, digit, digit_size);
197
 
             dummy=write (dev_dsp_fd, digit, digit_size);
198
 
 
199
 
             modem_write (modem_out_fd, silence, silence_size);
200
 
             modem_read (modem_in_fd, buf, silence_size);
201
 
             dummy=write (dev_dsp_fd, buf, silence_size);
202
 
           }
203
 
         phone_number++;
204
 
       }
205
 
  
206
 
  free(buf);
207
 
  free(silence);
208
 
  free(digit);
209
 
 
210
 
  printf("\n");
211
 
}
212
 
 
213
 
static void
214
 
usage(void)
215
 
{
216
 
  fprintf (stderr, "Usage: %s [options] mdmin-dev mdmout-dev [phone-number]\n", cmdname);
217
 
  fprintf (stderr, "  Options:  -d<devname>    Change sound device (default: %s)\n", dspdev_name);
218
 
  fprintf (stderr, "            -s<rate>       Change sampling rate (default: %d)\n", srate);
219
 
  fprintf (stderr, "            -t<duration>   Change DTMF digit duration (default: %.1f s)\n", digit_duration);
220
 
  fprintf (stderr, "            -l<duration>   Change DTMF silence duration (default: %.1f s)\n", silence_duration);
221
 
  exit (-1);
222
 
}
223
 
 
224
 
static void
225
 
exit_handler(void)
226
 
{
227
 
  if (modem_in_fd >= 0)
228
 
    {
229
 
      close (modem_in_fd);
230
 
      modem_in_fd = -1;
231
 
    }
232
 
  if (modem_out_fd >= 0)
233
 
    {
234
 
      int offhook = 0;
235
 
      printf("On-hook\n");
236
 
      ioctl (modem_out_fd, SNDCTL_DSP_MODEM_OFFHOOK, &offhook);
237
 
      close (modem_out_fd);
238
 
      modem_out_fd = -1;
239
 
    }
240
 
  if (dev_dsp_fd >= 0)
241
 
    {
242
 
      close (dev_dsp_fd);
243
 
      dev_dsp_fd = -1;
244
 
    }
245
 
}
246
 
 
247
 
static void
248
 
sigint_handler(int sig)
249
 
{
250
 
  exit (0);
251
 
}
252
 
 
253
 
int
254
 
main(int argc, char **argv)
255
 
{
256
 
  char *phone_number = "";
257
 
 
258
 
  int channels = 1;
259
 
  int format = AFMT_S16_LE;
260
 
 
261
 
  extern int optind;
262
 
  extern char *optarg;
263
 
  int c, tmp;
264
 
 
265
 
  cmdname=argv[0];
266
 
 
267
 
  signal(SIGINT, sigint_handler);
268
 
 
269
 
  if (argc < 3)
270
 
    {
271
 
      usage ();
272
 
    }
273
 
 
274
 
  while ((c = getopt (argc, argv, "d:s:t:l:")) != EOF)
275
 
    {
276
 
      switch (c)
277
 
      {
278
 
      case 'd':
279
 
              dspdev_name = optarg;
280
 
              break;
281
 
      case 's':
282
 
              srate = atoi (optarg);
283
 
              break;
284
 
      case 't':
285
 
              digit_duration = atof (optarg);
286
 
              break;
287
 
      case 'l':
288
 
              silence_duration = atof (optarg);
289
 
              break;
290
 
      default:
291
 
              usage ();
292
 
      }
293
 
    }
294
 
 
295
 
  if ((argc - optind) < 2)
296
 
      usage ();
297
 
 
298
 
  atexit(exit_handler);
299
 
 
300
 
  dev_dsp_fd = open (dspdev_name, O_RDWR);
301
 
  if (dev_dsp_fd < 0)
302
 
    {
303
 
      perror (dspdev_name);
304
 
      exit (-1);
305
 
    }
306
 
 
307
 
  modem_in_fd = open (argv[optind], O_RDWR);
308
 
  if (modem_in_fd < 0)
309
 
    {
310
 
      perror (argv[optind]);
311
 
      exit (-1);
312
 
    }
313
 
  tmp=0;
314
 
  ioctl(modem_in_fd, SNDCTL_DSP_COOKEDMODE, &tmp); // No error checking with this call
315
 
  optind++;
316
 
 
317
 
  modem_out_fd = open(argv[optind], O_RDWR);
318
 
  if (modem_out_fd < 0)
319
 
    {
320
 
      perror (argv[optind]);
321
 
      exit (-1);
322
 
    }
323
 
  tmp=0;
324
 
  ioctl(modem_out_fd, SNDCTL_DSP_COOKEDMODE, &tmp); // No error checking with this call
325
 
  optind++;
326
 
 
327
 
  if (argc > optind)
328
 
      phone_number = argv[optind];
329
 
 
330
 
  assert ( ioctl (modem_in_fd,  SNDCTL_DSP_CHANNELS, &channels) >= 0 );
331
 
  assert ( ioctl (modem_out_fd, SNDCTL_DSP_CHANNELS, &channels) >= 0 );
332
 
  assert ( ioctl (dev_dsp_fd, SNDCTL_DSP_CHANNELS, &channels) >= 0 );
333
 
 
334
 
  assert ( ioctl (modem_in_fd,  SNDCTL_DSP_SETFMT, &format) >= 0 );
335
 
  assert ( ioctl (modem_out_fd, SNDCTL_DSP_SETFMT, &format) >= 0 );
336
 
  assert ( ioctl (dev_dsp_fd, SNDCTL_DSP_SETFMT, &format) >= 0 );
337
 
 
338
 
  assert ( ioctl (modem_in_fd,  SNDCTL_DSP_SPEED, &srate) >= 0 );
339
 
  assert ( ioctl (modem_out_fd, SNDCTL_DSP_SPEED, &srate) >= 0 );
340
 
  assert ( ioctl (dev_dsp_fd, SNDCTL_DSP_SPEED, &srate) >= 0 );
341
 
 
342
 
  {
343
 
    int tmp;
344
 
    tmp = 0;
345
 
    assert ( ioctl (modem_in_fd,  SNDCTL_DSP_SETTRIGGER, &tmp) >= 0 );
346
 
    tmp = PCM_ENABLE_INPUT;
347
 
    assert ( ioctl (modem_in_fd,  SNDCTL_DSP_SETTRIGGER, &tmp) >= 0 );
348
 
    tmp = 0;
349
 
    assert ( ioctl (modem_out_fd, SNDCTL_DSP_SETTRIGGER, &tmp) >= 0 );
350
 
    tmp = PCM_ENABLE_OUTPUT;
351
 
    assert ( ioctl (modem_out_fd, SNDCTL_DSP_SETTRIGGER, &tmp) >= 0 );
352
 
    tmp = 0;
353
 
    assert ( ioctl (dev_dsp_fd, SNDCTL_DSP_SETTRIGGER, &tmp) >= 0 );
354
 
    tmp = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
355
 
    assert ( ioctl (dev_dsp_fd, SNDCTL_DSP_SETTRIGGER, &tmp) >= 0 );
356
 
  }
357
 
 
358
 
  go_offhook ();
359
 
 
360
 
  if (phone_number[0] != '\0')
361
 
  {
362
 
      if (wait_dialtone () < 0)
363
 
        {
364
 
          printf("No dial tone.\n");
365
 
          exit (-1);
366
 
        }
367
 
      dial_phone_number(phone_number);
368
 
    }
369
 
 
370
 
  printf("Call in progress...\n");
371
 
  printf("Press Ctrl-C to quit.\n");
372
 
 
373
 
  {
374
 
    uint16_t buf[128];
375
 
    fd_set rfds;
376
 
    int retval;
377
 
 
378
 
    int max_fd = modem_in_fd;
379
 
    if (dev_dsp_fd > max_fd)
380
 
        max_fd = dev_dsp_fd;
381
 
 
382
 
    while (1)
383
 
         {
384
 
           int dummy;
385
 
           FD_ZERO(&rfds);
386
 
           FD_SET(modem_in_fd, &rfds);
387
 
           FD_SET(dev_dsp_fd, &rfds);
388
 
 
389
 
           retval = select(max_fd+1, &rfds, NULL, NULL, NULL);
390
 
           if (retval == -1)
391
 
             {
392
 
               perror("select");
393
 
             }
394
 
           else if (retval)
395
 
             {
396
 
               if (FD_ISSET(modem_in_fd, &rfds))
397
 
                 {
398
 
                   modem_read(modem_in_fd, buf, sizeof(buf));
399
 
                   dummy=write(dev_dsp_fd, buf, sizeof(buf));
400
 
                 }
401
 
               if (FD_ISSET(dev_dsp_fd, &rfds))
402
 
                 {
403
 
                   dummy=read(dev_dsp_fd, buf, sizeof(buf));
404
 
                   modem_write(modem_out_fd, buf, sizeof(buf));
405
 
                 }
406
 
             }
407
 
         }
408
 
  }
409
 
 
410
 
  // return 0; /* NOT REACHED */
411
 
}
412