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/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
  44static 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};
  58static u32 sizeof_german_all = sizeof(sample_german_all);
  59
  60static 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};
  74static u32 sizeof_german_old = sizeof(sample_german_old);
  75
  76static 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};
  90static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
  91
  92static 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};
 115static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
 116
 117static 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};
 134static u32 sizeof_american_busy = sizeof(sample_american_busy);
 135
 136static 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};
 146static u32 sizeof_special1 = sizeof(sample_special1);
 147
 148static 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};
 160static u32 sizeof_special2 = sizeof(sample_special2);
 161
 162static 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};
 174static u32 sizeof_special3 = sizeof(sample_special3);
 175
 176static 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};
 190static u32 sizeof_silence = sizeof(sample_silence);
 191
 192struct tones_samples {
 193        u32 *len;
 194        u8 *data;
 195};
 196static struct
 197tones_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
 213void
 214dsp_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
 235static 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 */
 375void 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
 437static void
 438dsp_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 *****************/
 459void
 460dsp_tone_timeout(void *arg)
 461{
 462        struct dsp *dsp = arg;
 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        init_timer(&tone->tl);
 482        tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
 483        add_timer(&tone->tl);
 484}
 485
 486
 487/********************
 488 * set/release tone *
 489 ********************/
 490
 491/*
 492 * tones are relaized by streaming or by special loop commands if supported
 493 * by hardware. when hardware is used, the patterns will be controlled by
 494 * timers.
 495 */
 496int
 497dsp_tone(struct dsp *dsp, int tone)
 498{
 499        struct pattern *pat;
 500        int i;
 501        struct dsp_tone *tonet = &dsp->tone;
 502
 503        tonet->software = 0;
 504        tonet->hardware = 0;
 505
 506        /* we turn off the tone */
 507        if (!tone) {
 508                if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
 509                        del_timer(&tonet->tl);
 510                if (dsp->features.hfc_loops)
 511                        dsp_tone_hw_message(dsp, NULL, 0);
 512                tonet->tone = 0;
 513                return 0;
 514        }
 515
 516        pat = NULL;
 517        i = 0;
 518        while (pattern[i].tone) {
 519                if (pattern[i].tone == tone) {
 520                        pat = &pattern[i];
 521                        break;
 522                }
 523                i++;
 524        }
 525        if (!pat) {
 526                printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
 527                return -EINVAL;
 528        }
 529        if (dsp_debug & DEBUG_DSP_TONE)
 530                printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
 531                       __func__, tone, 0);
 532        tonet->tone = tone;
 533        tonet->pattern = pat;
 534        tonet->index = 0;
 535        tonet->count = 0;
 536
 537        if (dsp->features.hfc_loops) {
 538                tonet->hardware = 1;
 539                /* set first tone */
 540                dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
 541                /* set timer */
 542                if (timer_pending(&tonet->tl))
 543                        del_timer(&tonet->tl);
 544                init_timer(&tonet->tl);
 545                tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
 546                add_timer(&tonet->tl);
 547        } else {
 548                tonet->software = 1;
 549        }
 550
 551        return 0;
 552}
 553