root/drivers/isdn/mISDN/dsp_tones.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dsp_audio_generate_ulaw_samples
  2. dsp_tone_copy
  3. dsp_tone_hw_message
  4. dsp_tone_timeout
  5. dsp_tone

   1 /*
   2  * Audio support data for ISDN4Linux.
   3  *
   4  * Copyright Andreas Eversberg (jolly@eversberg.eu)
   5  *
   6  * This software may be used and distributed according to the terms
   7  * of the GNU General Public License, incorporated herein by reference.
   8  *
   9  */
  10 
  11 #include <linux/gfp.h>
  12 #include <linux/mISDNif.h>
  13 #include <linux/mISDNdsp.h>
  14 #include "core.h"
  15 #include "dsp.h"
  16 
  17 
  18 #define DATA_S sample_silence
  19 #define SIZE_S (&sizeof_silence)
  20 #define DATA_GA sample_german_all
  21 #define SIZE_GA (&sizeof_german_all)
  22 #define DATA_GO sample_german_old
  23 #define SIZE_GO (&sizeof_german_old)
  24 #define DATA_DT sample_american_dialtone
  25 #define SIZE_DT (&sizeof_american_dialtone)
  26 #define DATA_RI sample_american_ringing
  27 #define SIZE_RI (&sizeof_american_ringing)
  28 #define DATA_BU sample_american_busy
  29 #define SIZE_BU (&sizeof_american_busy)
  30 #define DATA_S1 sample_special1
  31 #define SIZE_S1 (&sizeof_special1)
  32 #define DATA_S2 sample_special2
  33 #define SIZE_S2 (&sizeof_special2)
  34 #define DATA_S3 sample_special3
  35 #define SIZE_S3 (&sizeof_special3)
  36 
  37 /***************/
  38 /* tones loops */
  39 /***************/
  40 
  41 /* all tones are alaw encoded */
  42 /* the last sample+1 is in phase with the first sample. the error is low */
  43 
  44 static u8 sample_german_all[] = {
  45         0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
  46         0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
  47         0xdc, 0xfc, 0x6c,
  48         0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
  49         0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
  50         0xdc, 0xfc, 0x6c,
  51         0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
  52         0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
  53         0xdc, 0xfc, 0x6c,
  54         0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
  55         0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
  56         0xdc, 0xfc, 0x6c,
  57 };
  58 static u32 sizeof_german_all = sizeof(sample_german_all);
  59 
  60 static u8 sample_german_old[] = {
  61         0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
  62         0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
  63         0x8c,
  64         0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
  65         0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
  66         0x8c,
  67         0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
  68         0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
  69         0x8c,
  70         0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
  71         0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
  72         0x8c,
  73 };
  74 static u32 sizeof_german_old = sizeof(sample_german_old);
  75 
  76 static u8 sample_american_dialtone[] = {
  77         0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
  78         0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
  79         0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
  80         0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
  81         0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
  82         0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
  83         0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
  84         0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
  85         0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
  86         0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
  87         0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
  88         0x6d, 0x91, 0x19,
  89 };
  90 static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
  91 
  92 static u8 sample_american_ringing[] = {
  93         0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
  94         0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
  95         0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
  96         0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
  97         0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
  98         0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
  99         0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
 100         0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
 101         0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
 102         0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
 103         0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
 104         0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
 105         0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
 106         0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
 107         0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
 108         0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
 109         0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
 110         0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
 111         0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
 112         0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
 113         0x4d, 0xbd, 0x0d, 0xad, 0xe1,
 114 };
 115 static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
 116 
 117 static u8 sample_american_busy[] = {
 118         0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
 119         0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
 120         0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
 121         0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
 122         0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
 123         0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
 124         0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
 125         0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
 126         0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
 127         0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
 128         0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
 129         0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
 130         0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
 131         0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
 132         0x4d, 0x4d, 0x6d, 0x01,
 133 };
 134 static u32 sizeof_american_busy = sizeof(sample_american_busy);
 135 
 136 static u8 sample_special1[] = {
 137         0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
 138         0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
 139         0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
 140         0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
 141         0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
 142         0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
 143         0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
 144         0x6d, 0xbd, 0x2d,
 145 };
 146 static u32 sizeof_special1 = sizeof(sample_special1);
 147 
 148 static u8 sample_special2[] = {
 149         0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
 150         0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
 151         0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
 152         0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
 153         0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
 154         0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
 155         0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
 156         0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
 157         0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
 158         0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
 159 };
 160 static u32 sizeof_special2 = sizeof(sample_special2);
 161 
 162 static u8 sample_special3[] = {
 163         0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
 164         0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
 165         0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
 166         0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
 167         0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
 168         0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
 169         0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
 170         0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
 171         0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
 172         0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
 173 };
 174 static u32 sizeof_special3 = sizeof(sample_special3);
 175 
 176 static u8 sample_silence[] = {
 177         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 178         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 179         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 180         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 181         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 182         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 183         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 184         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 185         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 186         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 187         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 188         0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
 189 };
 190 static u32 sizeof_silence = sizeof(sample_silence);
 191 
 192 struct tones_samples {
 193         u32 *len;
 194         u8 *data;
 195 };
 196 static struct
 197 tones_samples samples[] = {
 198         {&sizeof_german_all, sample_german_all},
 199         {&sizeof_german_old, sample_german_old},
 200         {&sizeof_american_dialtone, sample_american_dialtone},
 201         {&sizeof_american_ringing, sample_american_ringing},
 202         {&sizeof_american_busy, sample_american_busy},
 203         {&sizeof_special1, sample_special1},
 204         {&sizeof_special2, sample_special2},
 205         {&sizeof_special3, sample_special3},
 206         {NULL, NULL},
 207 };
 208 
 209 /***********************************
 210  * generate ulaw from alaw samples *
 211  ***********************************/
 212 
 213 void
 214 dsp_audio_generate_ulaw_samples(void)
 215 {
 216         int i, j;
 217 
 218         i = 0;
 219         while (samples[i].len) {
 220                 j = 0;
 221                 while (j < (*samples[i].len)) {
 222                         samples[i].data[j] =
 223                                 dsp_audio_alaw_to_ulaw[samples[i].data[j]];
 224                         j++;
 225                 }
 226                 i++;
 227         }
 228 }
 229 
 230 
 231 /****************************
 232  * tone sequence definition *
 233  ****************************/
 234 
 235 static struct pattern {
 236         int tone;
 237         u8 *data[10];
 238         u32 *siz[10];
 239         u32 seq[10];
 240 } pattern[] = {
 241         {TONE_GERMAN_DIALTONE,
 242          {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 243          {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 244          {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 245 
 246         {TONE_GERMAN_OLDDIALTONE,
 247          {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 248          {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 249          {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 250 
 251         {TONE_AMERICAN_DIALTONE,
 252          {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 253          {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 254          {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 255 
 256         {TONE_GERMAN_DIALPBX,
 257          {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
 258           NULL},
 259          {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
 260           NULL},
 261          {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 262 
 263         {TONE_GERMAN_OLDDIALPBX,
 264          {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
 265           NULL},
 266          {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
 267           NULL},
 268          {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 269 
 270         {TONE_AMERICAN_DIALPBX,
 271          {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
 272           NULL},
 273          {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
 274           NULL},
 275          {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 276 
 277         {TONE_GERMAN_RINGING,
 278          {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 279          {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 280          {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
 281 
 282         {TONE_GERMAN_OLDRINGING,
 283          {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 284          {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 285          {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
 286 
 287         {TONE_AMERICAN_RINGING,
 288          {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 289          {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 290          {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
 291 
 292         {TONE_GERMAN_RINGPBX,
 293          {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
 294          {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
 295          {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
 296 
 297         {TONE_GERMAN_OLDRINGPBX,
 298          {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
 299          {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
 300          {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
 301 
 302         {TONE_AMERICAN_RINGPBX,
 303          {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
 304          {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
 305          {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
 306 
 307         {TONE_GERMAN_BUSY,
 308          {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 309          {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 310          {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
 311 
 312         {TONE_GERMAN_OLDBUSY,
 313          {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 314          {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 315          {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
 316 
 317         {TONE_AMERICAN_BUSY,
 318          {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 319          {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 320          {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
 321 
 322         {TONE_GERMAN_HANGUP,
 323          {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 324          {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 325          {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
 326 
 327         {TONE_GERMAN_OLDHANGUP,
 328          {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 329          {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 330          {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
 331 
 332         {TONE_AMERICAN_HANGUP,
 333          {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 334          {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 335          {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 336 
 337         {TONE_SPECIAL_INFO,
 338          {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
 339          {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
 340          {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
 341 
 342         {TONE_GERMAN_GASSENBESETZT,
 343          {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 344          {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 345          {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
 346 
 347         {TONE_GERMAN_AUFSCHALTTON,
 348          {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
 349          {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
 350          {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
 351 
 352         {0,
 353          {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 354          {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 355          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 356 };
 357 
 358 /******************
 359  * copy tone data *
 360  ******************/
 361 
 362 /* an sk_buff is generated from the number of samples needed.
 363  * the count will be changed and may begin from 0 each pattern period.
 364  * the clue is to precalculate the pointers and legths to use only one
 365  * memcpy per function call, or two memcpy if the tone sequence changes.
 366  *
 367  * pattern - the type of the pattern
 368  * count - the sample from the beginning of the pattern (phase)
 369  * len - the number of bytes
 370  *
 371  * return - the sk_buff with the sample
 372  *
 373  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
 374  */
 375 void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
 376 {
 377         int index, count, start, num;
 378         struct pattern *pat;
 379         struct dsp_tone *tone = &dsp->tone;
 380 
 381         /* if we have no tone, we copy silence */
 382         if (!tone->tone) {
 383                 memset(data, dsp_silence, len);
 384                 return;
 385         }
 386 
 387         /* process pattern */
 388         pat = (struct pattern *)tone->pattern;
 389         /* points to the current pattern */
 390         index = tone->index; /* gives current sequence index */
 391         count = tone->count; /* gives current sample */
 392 
 393         /* copy sample */
 394         while (len) {
 395                 /* find sample to start with */
 396                 while (42) {
 397                         /* wrap around */
 398                         if (!pat->seq[index]) {
 399                                 count = 0;
 400                                 index = 0;
 401                         }
 402                         /* check if we are currently playing this tone */
 403                         if (count < pat->seq[index])
 404                                 break;
 405                         if (dsp_debug & DEBUG_DSP_TONE)
 406                                 printk(KERN_DEBUG "%s: reaching next sequence "
 407                                        "(index=%d)\n", __func__, index);
 408                         count -= pat->seq[index];
 409                         index++;
 410                 }
 411                 /* calculate start and number of samples */
 412                 start = count % (*(pat->siz[index]));
 413                 num = len;
 414                 if (num + count > pat->seq[index])
 415                         num = pat->seq[index] - count;
 416                 if (num + start > (*(pat->siz[index])))
 417                         num = (*(pat->siz[index])) - start;
 418                 /* copy memory */
 419                 memcpy(data, pat->data[index] + start, num);
 420                 /* reduce length */
 421                 data += num;
 422                 count += num;
 423                 len -= num;
 424         }
 425         tone->index = index;
 426         tone->count = count;
 427 
 428         /* return sk_buff */
 429         return;
 430 }
 431 
 432 
 433 /*******************************
 434  * send HW message to hfc card *
 435  *******************************/
 436 
 437 static void
 438 dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
 439 {
 440         struct sk_buff *nskb;
 441 
 442         /* unlocking is not required, because we don't expect a response */
 443         nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
 444                                 (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
 445                                 GFP_ATOMIC);
 446         if (nskb) {
 447                 if (dsp->ch.peer) {
 448                         if (dsp->ch.recv(dsp->ch.peer, nskb))
 449                                 dev_kfree_skb(nskb);
 450                 } else
 451                         dev_kfree_skb(nskb);
 452         }
 453 }
 454 
 455 
 456 /*****************
 457  * timer expires *
 458  *****************/
 459 void
 460 dsp_tone_timeout(struct timer_list *t)
 461 {
 462         struct dsp *dsp = from_timer(dsp, t, tone.tl);
 463         struct dsp_tone *tone = &dsp->tone;
 464         struct pattern *pat = (struct pattern *)tone->pattern;
 465         int index = tone->index;
 466 
 467         if (!tone->tone)
 468                 return;
 469 
 470         index++;
 471         if (!pat->seq[index])
 472                 index = 0;
 473         tone->index = index;
 474 
 475         /* set next tone */
 476         if (pat->data[index] == DATA_S)
 477                 dsp_tone_hw_message(dsp, NULL, 0);
 478         else
 479                 dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
 480         /* set timer */
 481         tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
 482         add_timer(&tone->tl);
 483 }
 484 
 485 
 486 /********************
 487  * set/release tone *
 488  ********************/
 489 
 490 /*
 491  * tones are relaized by streaming or by special loop commands if supported
 492  * by hardware. when hardware is used, the patterns will be controlled by
 493  * timers.
 494  */
 495 int
 496 dsp_tone(struct dsp *dsp, int tone)
 497 {
 498         struct pattern *pat;
 499         int i;
 500         struct dsp_tone *tonet = &dsp->tone;
 501 
 502         tonet->software = 0;
 503         tonet->hardware = 0;
 504 
 505         /* we turn off the tone */
 506         if (!tone) {
 507                 if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
 508                         del_timer(&tonet->tl);
 509                 if (dsp->features.hfc_loops)
 510                         dsp_tone_hw_message(dsp, NULL, 0);
 511                 tonet->tone = 0;
 512                 return 0;
 513         }
 514 
 515         pat = NULL;
 516         i = 0;
 517         while (pattern[i].tone) {
 518                 if (pattern[i].tone == tone) {
 519                         pat = &pattern[i];
 520                         break;
 521                 }
 522                 i++;
 523         }
 524         if (!pat) {
 525                 printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
 526                 return -EINVAL;
 527         }
 528         if (dsp_debug & DEBUG_DSP_TONE)
 529                 printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
 530                        __func__, tone, 0);
 531         tonet->tone = tone;
 532         tonet->pattern = pat;
 533         tonet->index = 0;
 534         tonet->count = 0;
 535 
 536         if (dsp->features.hfc_loops) {
 537                 tonet->hardware = 1;
 538                 /* set first tone */
 539                 dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
 540                 /* set timer */
 541                 if (timer_pending(&tonet->tl))
 542                         del_timer(&tonet->tl);
 543                 tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
 544                 add_timer(&tonet->tl);
 545         } else {
 546                 tonet->software = 1;
 547         }
 548 
 549         return 0;
 550 }

/* [<][>][^][v][top][bottom][index][help] */