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