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