Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Audio support data for ISDN4Linux.
0003  *
0004  * Copyright Andreas Eversberg (jolly@eversberg.eu)
0005  *
0006  * This software may be used and distributed according to the terms
0007  * of the GNU General Public License, incorporated herein by reference.
0008  *
0009  */
0010 
0011 #include <linux/gfp.h>
0012 #include <linux/mISDNif.h>
0013 #include <linux/mISDNdsp.h>
0014 #include "core.h"
0015 #include "dsp.h"
0016 
0017 
0018 #define DATA_S sample_silence
0019 #define SIZE_S (&sizeof_silence)
0020 #define DATA_GA sample_german_all
0021 #define SIZE_GA (&sizeof_german_all)
0022 #define DATA_GO sample_german_old
0023 #define SIZE_GO (&sizeof_german_old)
0024 #define DATA_DT sample_american_dialtone
0025 #define SIZE_DT (&sizeof_american_dialtone)
0026 #define DATA_RI sample_american_ringing
0027 #define SIZE_RI (&sizeof_american_ringing)
0028 #define DATA_BU sample_american_busy
0029 #define SIZE_BU (&sizeof_american_busy)
0030 #define DATA_S1 sample_special1
0031 #define SIZE_S1 (&sizeof_special1)
0032 #define DATA_S2 sample_special2
0033 #define SIZE_S2 (&sizeof_special2)
0034 #define DATA_S3 sample_special3
0035 #define SIZE_S3 (&sizeof_special3)
0036 
0037 /***************/
0038 /* tones loops */
0039 /***************/
0040 
0041 /* all tones are alaw encoded */
0042 /* the last sample+1 is in phase with the first sample. the error is low */
0043 
0044 static u8 sample_german_all[] = {
0045     0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
0046     0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
0047     0xdc, 0xfc, 0x6c,
0048     0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
0049     0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
0050     0xdc, 0xfc, 0x6c,
0051     0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
0052     0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
0053     0xdc, 0xfc, 0x6c,
0054     0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
0055     0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
0056     0xdc, 0xfc, 0x6c,
0057 };
0058 static u32 sizeof_german_all = sizeof(sample_german_all);
0059 
0060 static u8 sample_german_old[] = {
0061     0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
0062     0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
0063     0x8c,
0064     0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
0065     0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
0066     0x8c,
0067     0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
0068     0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
0069     0x8c,
0070     0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
0071     0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
0072     0x8c,
0073 };
0074 static u32 sizeof_german_old = sizeof(sample_german_old);
0075 
0076 static u8 sample_american_dialtone[] = {
0077     0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
0078     0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
0079     0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
0080     0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
0081     0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
0082     0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
0083     0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
0084     0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
0085     0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
0086     0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
0087     0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
0088     0x6d, 0x91, 0x19,
0089 };
0090 static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
0091 
0092 static u8 sample_american_ringing[] = {
0093     0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
0094     0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
0095     0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
0096     0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
0097     0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
0098     0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
0099     0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
0100     0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
0101     0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
0102     0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
0103     0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
0104     0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
0105     0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
0106     0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
0107     0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
0108     0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
0109     0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
0110     0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
0111     0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
0112     0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
0113     0x4d, 0xbd, 0x0d, 0xad, 0xe1,
0114 };
0115 static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
0116 
0117 static u8 sample_american_busy[] = {
0118     0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
0119     0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
0120     0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
0121     0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
0122     0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
0123     0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
0124     0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
0125     0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
0126     0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
0127     0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
0128     0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
0129     0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
0130     0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
0131     0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
0132     0x4d, 0x4d, 0x6d, 0x01,
0133 };
0134 static u32 sizeof_american_busy = sizeof(sample_american_busy);
0135 
0136 static u8 sample_special1[] = {
0137     0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
0138     0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
0139     0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
0140     0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
0141     0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
0142     0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
0143     0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
0144     0x6d, 0xbd, 0x2d,
0145 };
0146 static u32 sizeof_special1 = sizeof(sample_special1);
0147 
0148 static u8 sample_special2[] = {
0149     0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
0150     0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
0151     0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
0152     0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
0153     0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
0154     0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
0155     0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
0156     0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
0157     0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
0158     0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
0159 };
0160 static u32 sizeof_special2 = sizeof(sample_special2);
0161 
0162 static u8 sample_special3[] = {
0163     0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
0164     0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
0165     0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
0166     0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
0167     0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
0168     0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
0169     0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
0170     0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
0171     0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
0172     0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
0173 };
0174 static u32 sizeof_special3 = sizeof(sample_special3);
0175 
0176 static u8 sample_silence[] = {
0177     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0178     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0179     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0180     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0181     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0182     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0183     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0184     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0185     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0186     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0187     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0188     0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
0189 };
0190 static u32 sizeof_silence = sizeof(sample_silence);
0191 
0192 struct tones_samples {
0193     u32 *len;
0194     u8 *data;
0195 };
0196 static struct
0197 tones_samples samples[] = {
0198     {&sizeof_german_all, sample_german_all},
0199     {&sizeof_german_old, sample_german_old},
0200     {&sizeof_american_dialtone, sample_american_dialtone},
0201     {&sizeof_american_ringing, sample_american_ringing},
0202     {&sizeof_american_busy, sample_american_busy},
0203     {&sizeof_special1, sample_special1},
0204     {&sizeof_special2, sample_special2},
0205     {&sizeof_special3, sample_special3},
0206     {NULL, NULL},
0207 };
0208 
0209 /***********************************
0210  * generate ulaw from alaw samples *
0211  ***********************************/
0212 
0213 void
0214 dsp_audio_generate_ulaw_samples(void)
0215 {
0216     int i, j;
0217 
0218     i = 0;
0219     while (samples[i].len) {
0220         j = 0;
0221         while (j < (*samples[i].len)) {
0222             samples[i].data[j] =
0223                 dsp_audio_alaw_to_ulaw[samples[i].data[j]];
0224             j++;
0225         }
0226         i++;
0227     }
0228 }
0229 
0230 
0231 /****************************
0232  * tone sequence definition *
0233  ****************************/
0234 
0235 static struct pattern {
0236     int tone;
0237     u8 *data[10];
0238     u32 *siz[10];
0239     u32 seq[10];
0240 } pattern[] = {
0241     {TONE_GERMAN_DIALTONE,
0242      {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0243      {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0244      {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
0245 
0246     {TONE_GERMAN_OLDDIALTONE,
0247      {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0248      {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0249      {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
0250 
0251     {TONE_AMERICAN_DIALTONE,
0252      {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0253      {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0254      {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
0255 
0256     {TONE_GERMAN_DIALPBX,
0257      {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
0258       NULL},
0259      {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
0260       NULL},
0261      {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
0262 
0263     {TONE_GERMAN_OLDDIALPBX,
0264      {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
0265       NULL},
0266      {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
0267       NULL},
0268      {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
0269 
0270     {TONE_AMERICAN_DIALPBX,
0271      {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
0272       NULL},
0273      {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
0274       NULL},
0275      {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
0276 
0277     {TONE_GERMAN_RINGING,
0278      {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0279      {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0280      {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
0281 
0282     {TONE_GERMAN_OLDRINGING,
0283      {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0284      {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0285      {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
0286 
0287     {TONE_AMERICAN_RINGING,
0288      {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0289      {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0290      {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
0291 
0292     {TONE_GERMAN_RINGPBX,
0293      {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
0294      {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
0295      {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
0296 
0297     {TONE_GERMAN_OLDRINGPBX,
0298      {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
0299      {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
0300      {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
0301 
0302     {TONE_AMERICAN_RINGPBX,
0303      {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
0304      {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
0305      {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
0306 
0307     {TONE_GERMAN_BUSY,
0308      {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0309      {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0310      {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
0311 
0312     {TONE_GERMAN_OLDBUSY,
0313      {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0314      {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0315      {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
0316 
0317     {TONE_AMERICAN_BUSY,
0318      {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0319      {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0320      {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
0321 
0322     {TONE_GERMAN_HANGUP,
0323      {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0324      {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0325      {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
0326 
0327     {TONE_GERMAN_OLDHANGUP,
0328      {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0329      {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0330      {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
0331 
0332     {TONE_AMERICAN_HANGUP,
0333      {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0334      {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0335      {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
0336 
0337     {TONE_SPECIAL_INFO,
0338      {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
0339      {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
0340      {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
0341 
0342     {TONE_GERMAN_GASSENBESETZT,
0343      {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0344      {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0345      {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
0346 
0347     {TONE_GERMAN_AUFSCHALTTON,
0348      {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
0349      {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
0350      {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
0351 
0352     {0,
0353      {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0354      {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
0355      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
0356 };
0357 
0358 /******************
0359  * copy tone data *
0360  ******************/
0361 
0362 /* an sk_buff is generated from the number of samples needed.
0363  * the count will be changed and may begin from 0 each pattern period.
0364  * the clue is to precalculate the pointers and legths to use only one
0365  * memcpy per function call, or two memcpy if the tone sequence changes.
0366  *
0367  * pattern - the type of the pattern
0368  * count - the sample from the beginning of the pattern (phase)
0369  * len - the number of bytes
0370  *
0371  * return - the sk_buff with the sample
0372  *
0373  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
0374  */
0375 void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
0376 {
0377     int index, count, start, num;
0378     struct pattern *pat;
0379     struct dsp_tone *tone = &dsp->tone;
0380 
0381     /* if we have no tone, we copy silence */
0382     if (!tone->tone) {
0383         memset(data, dsp_silence, len);
0384         return;
0385     }
0386 
0387     /* process pattern */
0388     pat = (struct pattern *)tone->pattern;
0389     /* points to the current pattern */
0390     index = tone->index; /* gives current sequence index */
0391     count = tone->count; /* gives current sample */
0392 
0393     /* copy sample */
0394     while (len) {
0395         /* find sample to start with */
0396         while (42) {
0397             /* wrap around */
0398             if (!pat->seq[index]) {
0399                 count = 0;
0400                 index = 0;
0401             }
0402             /* check if we are currently playing this tone */
0403             if (count < pat->seq[index])
0404                 break;
0405             if (dsp_debug & DEBUG_DSP_TONE)
0406                 printk(KERN_DEBUG "%s: reaching next sequence "
0407                        "(index=%d)\n", __func__, index);
0408             count -= pat->seq[index];
0409             index++;
0410         }
0411         /* calculate start and number of samples */
0412         start = count % (*(pat->siz[index]));
0413         num = len;
0414         if (num + count > pat->seq[index])
0415             num = pat->seq[index] - count;
0416         if (num + start > (*(pat->siz[index])))
0417             num = (*(pat->siz[index])) - start;
0418         /* copy memory */
0419         memcpy(data, pat->data[index] + start, num);
0420         /* reduce length */
0421         data += num;
0422         count += num;
0423         len -= num;
0424     }
0425     tone->index = index;
0426     tone->count = count;
0427 
0428     /* return sk_buff */
0429     return;
0430 }
0431 
0432 
0433 /*******************************
0434  * send HW message to hfc card *
0435  *******************************/
0436 
0437 static void
0438 dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
0439 {
0440     struct sk_buff *nskb;
0441 
0442     /* unlocking is not required, because we don't expect a response */
0443     nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
0444                 (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
0445                 GFP_ATOMIC);
0446     if (nskb) {
0447         if (dsp->ch.peer) {
0448             if (dsp->ch.recv(dsp->ch.peer, nskb))
0449                 dev_kfree_skb(nskb);
0450         } else
0451             dev_kfree_skb(nskb);
0452     }
0453 }
0454 
0455 
0456 /*****************
0457  * timer expires *
0458  *****************/
0459 void
0460 dsp_tone_timeout(struct timer_list *t)
0461 {
0462     struct dsp *dsp = from_timer(dsp, t, tone.tl);
0463     struct dsp_tone *tone = &dsp->tone;
0464     struct pattern *pat = (struct pattern *)tone->pattern;
0465     int index = tone->index;
0466 
0467     if (!tone->tone)
0468         return;
0469 
0470     index++;
0471     if (!pat->seq[index])
0472         index = 0;
0473     tone->index = index;
0474 
0475     /* set next tone */
0476     if (pat->data[index] == DATA_S)
0477         dsp_tone_hw_message(dsp, NULL, 0);
0478     else
0479         dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
0480     /* set timer */
0481     tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
0482     add_timer(&tone->tl);
0483 }
0484 
0485 
0486 /********************
0487  * set/release tone *
0488  ********************/
0489 
0490 /*
0491  * tones are relaized by streaming or by special loop commands if supported
0492  * by hardware. when hardware is used, the patterns will be controlled by
0493  * timers.
0494  */
0495 int
0496 dsp_tone(struct dsp *dsp, int tone)
0497 {
0498     struct pattern *pat;
0499     int i;
0500     struct dsp_tone *tonet = &dsp->tone;
0501 
0502     tonet->software = 0;
0503     tonet->hardware = 0;
0504 
0505     /* we turn off the tone */
0506     if (!tone) {
0507         if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
0508             del_timer(&tonet->tl);
0509         if (dsp->features.hfc_loops)
0510             dsp_tone_hw_message(dsp, NULL, 0);
0511         tonet->tone = 0;
0512         return 0;
0513     }
0514 
0515     pat = NULL;
0516     i = 0;
0517     while (pattern[i].tone) {
0518         if (pattern[i].tone == tone) {
0519             pat = &pattern[i];
0520             break;
0521         }
0522         i++;
0523     }
0524     if (!pat) {
0525         printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
0526         return -EINVAL;
0527     }
0528     if (dsp_debug & DEBUG_DSP_TONE)
0529         printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
0530                __func__, tone, 0);
0531     tonet->tone = tone;
0532     tonet->pattern = pat;
0533     tonet->index = 0;
0534     tonet->count = 0;
0535 
0536     if (dsp->features.hfc_loops) {
0537         tonet->hardware = 1;
0538         /* set first tone */
0539         dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
0540         /* set timer */
0541         if (timer_pending(&tonet->tl))
0542             del_timer(&tonet->tl);
0543         tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
0544         add_timer(&tonet->tl);
0545     } else {
0546         tonet->software = 1;
0547     }
0548 
0549     return 0;
0550 }