1960366cfSKarsten Keil /* 2960366cfSKarsten Keil * Audio support data for ISDN4Linux. 3960366cfSKarsten Keil * 4960366cfSKarsten Keil * Copyright Andreas Eversberg (jolly@eversberg.eu) 5960366cfSKarsten Keil * 6960366cfSKarsten Keil * This software may be used and distributed according to the terms 7960366cfSKarsten Keil * of the GNU General Public License, incorporated herein by reference. 8960366cfSKarsten Keil * 9960366cfSKarsten Keil */ 10960366cfSKarsten Keil 11960366cfSKarsten Keil #include <linux/mISDNif.h> 12960366cfSKarsten Keil #include <linux/mISDNdsp.h> 13960366cfSKarsten Keil #include "core.h" 14960366cfSKarsten Keil #include "dsp.h" 15960366cfSKarsten Keil 16960366cfSKarsten Keil 17960366cfSKarsten Keil #define DATA_S sample_silence 18960366cfSKarsten Keil #define SIZE_S (&sizeof_silence) 19960366cfSKarsten Keil #define DATA_GA sample_german_all 20960366cfSKarsten Keil #define SIZE_GA (&sizeof_german_all) 21960366cfSKarsten Keil #define DATA_GO sample_german_old 22960366cfSKarsten Keil #define SIZE_GO (&sizeof_german_old) 23960366cfSKarsten Keil #define DATA_DT sample_american_dialtone 24960366cfSKarsten Keil #define SIZE_DT (&sizeof_american_dialtone) 25960366cfSKarsten Keil #define DATA_RI sample_american_ringing 26960366cfSKarsten Keil #define SIZE_RI (&sizeof_american_ringing) 27960366cfSKarsten Keil #define DATA_BU sample_american_busy 28960366cfSKarsten Keil #define SIZE_BU (&sizeof_american_busy) 29960366cfSKarsten Keil #define DATA_S1 sample_special1 30960366cfSKarsten Keil #define SIZE_S1 (&sizeof_special1) 31960366cfSKarsten Keil #define DATA_S2 sample_special2 32960366cfSKarsten Keil #define SIZE_S2 (&sizeof_special2) 33960366cfSKarsten Keil #define DATA_S3 sample_special3 34960366cfSKarsten Keil #define SIZE_S3 (&sizeof_special3) 35960366cfSKarsten Keil 36960366cfSKarsten Keil /***************/ 37960366cfSKarsten Keil /* tones loops */ 38960366cfSKarsten Keil /***************/ 39960366cfSKarsten Keil 40960366cfSKarsten Keil /* all tones are alaw encoded */ 41960366cfSKarsten Keil /* the last sample+1 is in phase with the first sample. the error is low */ 42960366cfSKarsten Keil 43960366cfSKarsten Keil static u8 sample_german_all[] = { 44960366cfSKarsten Keil 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 45960366cfSKarsten Keil 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 46960366cfSKarsten Keil 0xdc, 0xfc, 0x6c, 47960366cfSKarsten Keil 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 48960366cfSKarsten Keil 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 49960366cfSKarsten Keil 0xdc, 0xfc, 0x6c, 50960366cfSKarsten Keil 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 51960366cfSKarsten Keil 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 52960366cfSKarsten Keil 0xdc, 0xfc, 0x6c, 53960366cfSKarsten Keil 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d, 54960366cfSKarsten Keil 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c, 55960366cfSKarsten Keil 0xdc, 0xfc, 0x6c, 56960366cfSKarsten Keil }; 57960366cfSKarsten Keil static u32 sizeof_german_all = sizeof(sample_german_all); 58960366cfSKarsten Keil 59960366cfSKarsten Keil static u8 sample_german_old[] = { 60960366cfSKarsten Keil 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 61960366cfSKarsten Keil 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 62960366cfSKarsten Keil 0x8c, 63960366cfSKarsten Keil 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 64960366cfSKarsten Keil 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 65960366cfSKarsten Keil 0x8c, 66960366cfSKarsten Keil 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 67960366cfSKarsten Keil 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 68960366cfSKarsten Keil 0x8c, 69960366cfSKarsten Keil 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed, 70960366cfSKarsten Keil 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70, 71960366cfSKarsten Keil 0x8c, 72960366cfSKarsten Keil }; 73960366cfSKarsten Keil static u32 sizeof_german_old = sizeof(sample_german_old); 74960366cfSKarsten Keil 75960366cfSKarsten Keil static u8 sample_american_dialtone[] = { 76960366cfSKarsten Keil 0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c, 77960366cfSKarsten Keil 0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d, 78960366cfSKarsten Keil 0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0, 79960366cfSKarsten Keil 0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67, 80960366cfSKarsten Keil 0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67, 81960366cfSKarsten Keil 0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef, 82960366cfSKarsten Keil 0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8, 83960366cfSKarsten Keil 0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61, 84960366cfSKarsten Keil 0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e, 85960366cfSKarsten Keil 0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30, 86960366cfSKarsten Keil 0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d, 87960366cfSKarsten Keil 0x6d, 0x91, 0x19, 88960366cfSKarsten Keil }; 89960366cfSKarsten Keil static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone); 90960366cfSKarsten Keil 91960366cfSKarsten Keil static u8 sample_american_ringing[] = { 92960366cfSKarsten Keil 0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90, 93960366cfSKarsten Keil 0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed, 94960366cfSKarsten Keil 0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c, 95960366cfSKarsten Keil 0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d, 96960366cfSKarsten Keil 0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec, 97960366cfSKarsten Keil 0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11, 98960366cfSKarsten Keil 0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00, 99960366cfSKarsten Keil 0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39, 100960366cfSKarsten Keil 0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6, 101960366cfSKarsten Keil 0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3, 102960366cfSKarsten Keil 0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b, 103960366cfSKarsten Keil 0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f, 104960366cfSKarsten Keil 0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56, 105960366cfSKarsten Keil 0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59, 106960366cfSKarsten Keil 0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30, 107960366cfSKarsten Keil 0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d, 108960366cfSKarsten Keil 0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c, 109960366cfSKarsten Keil 0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd, 110960366cfSKarsten Keil 0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc, 111960366cfSKarsten Keil 0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d, 112960366cfSKarsten Keil 0x4d, 0xbd, 0x0d, 0xad, 0xe1, 113960366cfSKarsten Keil }; 114960366cfSKarsten Keil static u32 sizeof_american_ringing = sizeof(sample_american_ringing); 115960366cfSKarsten Keil 116960366cfSKarsten Keil static u8 sample_american_busy[] = { 117960366cfSKarsten Keil 0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66, 118960366cfSKarsten Keil 0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96, 119960366cfSKarsten Keil 0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57, 120960366cfSKarsten Keil 0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f, 121960366cfSKarsten Keil 0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40, 122960366cfSKarsten Keil 0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d, 123960366cfSKarsten Keil 0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c, 124960366cfSKarsten Keil 0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d, 125960366cfSKarsten Keil 0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40, 126960366cfSKarsten Keil 0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7, 127960366cfSKarsten Keil 0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a, 128960366cfSKarsten Keil 0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7, 129960366cfSKarsten Keil 0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40, 130960366cfSKarsten Keil 0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d, 131960366cfSKarsten Keil 0x4d, 0x4d, 0x6d, 0x01, 132960366cfSKarsten Keil }; 133960366cfSKarsten Keil static u32 sizeof_american_busy = sizeof(sample_american_busy); 134960366cfSKarsten Keil 135960366cfSKarsten Keil static u8 sample_special1[] = { 136960366cfSKarsten Keil 0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d, 137960366cfSKarsten Keil 0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd, 138960366cfSKarsten Keil 0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd, 139960366cfSKarsten Keil 0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd, 140960366cfSKarsten Keil 0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed, 141960366cfSKarsten Keil 0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41, 142960366cfSKarsten Keil 0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7, 143960366cfSKarsten Keil 0x6d, 0xbd, 0x2d, 144960366cfSKarsten Keil }; 145960366cfSKarsten Keil static u32 sizeof_special1 = sizeof(sample_special1); 146960366cfSKarsten Keil 147960366cfSKarsten Keil static u8 sample_special2[] = { 148960366cfSKarsten Keil 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc, 149960366cfSKarsten Keil 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d, 150960366cfSKarsten Keil 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6, 151960366cfSKarsten Keil 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0, 152960366cfSKarsten Keil 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd, 153960366cfSKarsten Keil 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc, 154960366cfSKarsten Keil 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d, 155960366cfSKarsten Keil 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6, 156960366cfSKarsten Keil 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0, 157960366cfSKarsten Keil 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd, 158960366cfSKarsten Keil }; 159960366cfSKarsten Keil static u32 sizeof_special2 = sizeof(sample_special2); 160960366cfSKarsten Keil 161960366cfSKarsten Keil static u8 sample_special3[] = { 162960366cfSKarsten Keil 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1, 163960366cfSKarsten Keil 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c, 164960366cfSKarsten Keil 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc, 165960366cfSKarsten Keil 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7, 166960366cfSKarsten Keil 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd, 167960366cfSKarsten Keil 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1, 168960366cfSKarsten Keil 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c, 169960366cfSKarsten Keil 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc, 170960366cfSKarsten Keil 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7, 171960366cfSKarsten Keil 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd, 172960366cfSKarsten Keil }; 173960366cfSKarsten Keil static u32 sizeof_special3 = sizeof(sample_special3); 174960366cfSKarsten Keil 175960366cfSKarsten Keil static u8 sample_silence[] = { 176960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 177960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 178960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 179960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 180960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 181960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 182960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 183960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 184960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 185960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 186960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 187960366cfSKarsten Keil 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 188960366cfSKarsten Keil }; 189960366cfSKarsten Keil static u32 sizeof_silence = sizeof(sample_silence); 190960366cfSKarsten Keil 191960366cfSKarsten Keil struct tones_samples { 192960366cfSKarsten Keil u32 *len; 193960366cfSKarsten Keil u8 *data; 194960366cfSKarsten Keil }; 195960366cfSKarsten Keil static struct 196960366cfSKarsten Keil tones_samples samples[] = { 197960366cfSKarsten Keil {&sizeof_german_all, sample_german_all}, 198960366cfSKarsten Keil {&sizeof_german_old, sample_german_old}, 199960366cfSKarsten Keil {&sizeof_american_dialtone, sample_american_dialtone}, 200960366cfSKarsten Keil {&sizeof_american_ringing, sample_american_ringing}, 201960366cfSKarsten Keil {&sizeof_american_busy, sample_american_busy}, 202960366cfSKarsten Keil {&sizeof_special1, sample_special1}, 203960366cfSKarsten Keil {&sizeof_special2, sample_special2}, 204960366cfSKarsten Keil {&sizeof_special3, sample_special3}, 205960366cfSKarsten Keil {NULL, NULL}, 206960366cfSKarsten Keil }; 207960366cfSKarsten Keil 208960366cfSKarsten Keil /*********************************** 209960366cfSKarsten Keil * generate ulaw from alaw samples * 210960366cfSKarsten Keil ***********************************/ 211960366cfSKarsten Keil 212960366cfSKarsten Keil void 213960366cfSKarsten Keil dsp_audio_generate_ulaw_samples(void) 214960366cfSKarsten Keil { 215960366cfSKarsten Keil int i, j; 216960366cfSKarsten Keil 217960366cfSKarsten Keil i = 0; 218960366cfSKarsten Keil while (samples[i].len) { 219960366cfSKarsten Keil j = 0; 220960366cfSKarsten Keil while (j < (*samples[i].len)) { 221960366cfSKarsten Keil samples[i].data[j] = 222960366cfSKarsten Keil dsp_audio_alaw_to_ulaw[samples[i].data[j]]; 223960366cfSKarsten Keil j++; 224960366cfSKarsten Keil } 225960366cfSKarsten Keil i++; 226960366cfSKarsten Keil } 227960366cfSKarsten Keil } 228960366cfSKarsten Keil 229960366cfSKarsten Keil 230960366cfSKarsten Keil /**************************** 231960366cfSKarsten Keil * tone sequence definition * 232960366cfSKarsten Keil ****************************/ 233960366cfSKarsten Keil 234*5b834354SHannes Eder static struct pattern { 235960366cfSKarsten Keil int tone; 236960366cfSKarsten Keil u8 *data[10]; 237960366cfSKarsten Keil u32 *siz[10]; 238960366cfSKarsten Keil u32 seq[10]; 239960366cfSKarsten Keil } pattern[] = { 240960366cfSKarsten Keil {TONE_GERMAN_DIALTONE, 241bcf91745SHannes Eder {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 242bcf91745SHannes Eder {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 243960366cfSKarsten Keil {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 244960366cfSKarsten Keil 245960366cfSKarsten Keil {TONE_GERMAN_OLDDIALTONE, 246bcf91745SHannes Eder {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 247bcf91745SHannes Eder {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 248960366cfSKarsten Keil {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 249960366cfSKarsten Keil 250960366cfSKarsten Keil {TONE_AMERICAN_DIALTONE, 251bcf91745SHannes Eder {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 252bcf91745SHannes Eder {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 253960366cfSKarsten Keil {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 254960366cfSKarsten Keil 255960366cfSKarsten Keil {TONE_GERMAN_DIALPBX, 256bcf91745SHannes Eder {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL}, 257bcf91745SHannes Eder {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL}, 258960366cfSKarsten Keil {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, 259960366cfSKarsten Keil 260960366cfSKarsten Keil {TONE_GERMAN_OLDDIALPBX, 261bcf91745SHannes Eder {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL}, 262bcf91745SHannes Eder {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL}, 263960366cfSKarsten Keil {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, 264960366cfSKarsten Keil 265960366cfSKarsten Keil {TONE_AMERICAN_DIALPBX, 266bcf91745SHannes Eder {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, NULL}, 267bcf91745SHannes Eder {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, NULL}, 268960366cfSKarsten Keil {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, 269960366cfSKarsten Keil 270960366cfSKarsten Keil {TONE_GERMAN_RINGING, 271bcf91745SHannes Eder {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 272bcf91745SHannes Eder {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 273960366cfSKarsten Keil {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} }, 274960366cfSKarsten Keil 275960366cfSKarsten Keil {TONE_GERMAN_OLDRINGING, 276bcf91745SHannes Eder {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 277bcf91745SHannes Eder {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 278960366cfSKarsten Keil {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} }, 279960366cfSKarsten Keil 280960366cfSKarsten Keil {TONE_AMERICAN_RINGING, 281bcf91745SHannes Eder {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 282bcf91745SHannes Eder {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 283960366cfSKarsten Keil {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} }, 284960366cfSKarsten Keil 285960366cfSKarsten Keil {TONE_GERMAN_RINGPBX, 286bcf91745SHannes Eder {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 287bcf91745SHannes Eder {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 288960366cfSKarsten Keil {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, 289960366cfSKarsten Keil 290960366cfSKarsten Keil {TONE_GERMAN_OLDRINGPBX, 291bcf91745SHannes Eder {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 292bcf91745SHannes Eder {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 293960366cfSKarsten Keil {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, 294960366cfSKarsten Keil 295960366cfSKarsten Keil {TONE_AMERICAN_RINGPBX, 296bcf91745SHannes Eder {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 297bcf91745SHannes Eder {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 298960366cfSKarsten Keil {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} }, 299960366cfSKarsten Keil 300960366cfSKarsten Keil {TONE_GERMAN_BUSY, 301bcf91745SHannes Eder {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 302bcf91745SHannes Eder {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 303960366cfSKarsten Keil {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, 304960366cfSKarsten Keil 305960366cfSKarsten Keil {TONE_GERMAN_OLDBUSY, 306bcf91745SHannes Eder {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 307bcf91745SHannes Eder {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 308960366cfSKarsten Keil {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} }, 309960366cfSKarsten Keil 310960366cfSKarsten Keil {TONE_AMERICAN_BUSY, 311bcf91745SHannes Eder {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 312bcf91745SHannes Eder {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 313960366cfSKarsten Keil {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, 314960366cfSKarsten Keil 315960366cfSKarsten Keil {TONE_GERMAN_HANGUP, 316bcf91745SHannes Eder {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 317bcf91745SHannes Eder {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 318960366cfSKarsten Keil {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} }, 319960366cfSKarsten Keil 320960366cfSKarsten Keil {TONE_GERMAN_OLDHANGUP, 321bcf91745SHannes Eder {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 322bcf91745SHannes Eder {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 323960366cfSKarsten Keil {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} }, 324960366cfSKarsten Keil 325960366cfSKarsten Keil {TONE_AMERICAN_HANGUP, 326bcf91745SHannes Eder {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 327bcf91745SHannes Eder {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 328960366cfSKarsten Keil {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 329960366cfSKarsten Keil 330960366cfSKarsten Keil {TONE_SPECIAL_INFO, 331bcf91745SHannes Eder {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 332bcf91745SHannes Eder {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 333960366cfSKarsten Keil {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} }, 334960366cfSKarsten Keil 335960366cfSKarsten Keil {TONE_GERMAN_GASSENBESETZT, 336bcf91745SHannes Eder {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 337bcf91745SHannes Eder {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 338960366cfSKarsten Keil {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} }, 339960366cfSKarsten Keil 340960366cfSKarsten Keil {TONE_GERMAN_AUFSCHALTTON, 341bcf91745SHannes Eder {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL}, 342bcf91745SHannes Eder {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL}, 343960366cfSKarsten Keil {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} }, 344960366cfSKarsten Keil 345960366cfSKarsten Keil {0, 346bcf91745SHannes Eder {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 347bcf91745SHannes Eder {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, 348960366cfSKarsten Keil {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, 349960366cfSKarsten Keil }; 350960366cfSKarsten Keil 351960366cfSKarsten Keil /****************** 352960366cfSKarsten Keil * copy tone data * 353960366cfSKarsten Keil ******************/ 354960366cfSKarsten Keil 355960366cfSKarsten Keil /* an sk_buff is generated from the number of samples needed. 356960366cfSKarsten Keil * the count will be changed and may begin from 0 each pattern period. 357960366cfSKarsten Keil * the clue is to precalculate the pointers and legths to use only one 358960366cfSKarsten Keil * memcpy per function call, or two memcpy if the tone sequence changes. 359960366cfSKarsten Keil * 360960366cfSKarsten Keil * pattern - the type of the pattern 361960366cfSKarsten Keil * count - the sample from the beginning of the pattern (phase) 362960366cfSKarsten Keil * len - the number of bytes 363960366cfSKarsten Keil * 364960366cfSKarsten Keil * return - the sk_buff with the sample 365960366cfSKarsten Keil * 366960366cfSKarsten Keil * if tones has finished (e.g. knocking tone), dsp->tones is turned off 367960366cfSKarsten Keil */ 368960366cfSKarsten Keil void dsp_tone_copy(struct dsp *dsp, u8 *data, int len) 369960366cfSKarsten Keil { 370960366cfSKarsten Keil int index, count, start, num; 371960366cfSKarsten Keil struct pattern *pat; 372960366cfSKarsten Keil struct dsp_tone *tone = &dsp->tone; 373960366cfSKarsten Keil 374960366cfSKarsten Keil /* if we have no tone, we copy silence */ 375960366cfSKarsten Keil if (!tone->tone) { 376960366cfSKarsten Keil memset(data, dsp_silence, len); 377960366cfSKarsten Keil return; 378960366cfSKarsten Keil } 379960366cfSKarsten Keil 380960366cfSKarsten Keil /* process pattern */ 381960366cfSKarsten Keil pat = (struct pattern *)tone->pattern; 382960366cfSKarsten Keil /* points to the current pattern */ 383960366cfSKarsten Keil index = tone->index; /* gives current sequence index */ 384960366cfSKarsten Keil count = tone->count; /* gives current sample */ 385960366cfSKarsten Keil 386960366cfSKarsten Keil /* copy sample */ 387960366cfSKarsten Keil while (len) { 388960366cfSKarsten Keil /* find sample to start with */ 389960366cfSKarsten Keil while (42) { 390960366cfSKarsten Keil /* warp arround */ 391960366cfSKarsten Keil if (!pat->seq[index]) { 392960366cfSKarsten Keil count = 0; 393960366cfSKarsten Keil index = 0; 394960366cfSKarsten Keil } 395960366cfSKarsten Keil /* check if we are currently playing this tone */ 396960366cfSKarsten Keil if (count < pat->seq[index]) 397960366cfSKarsten Keil break; 398960366cfSKarsten Keil if (dsp_debug & DEBUG_DSP_TONE) 399960366cfSKarsten Keil printk(KERN_DEBUG "%s: reaching next sequence " 400960366cfSKarsten Keil "(index=%d)\n", __func__, index); 401960366cfSKarsten Keil count -= pat->seq[index]; 402960366cfSKarsten Keil index++; 403960366cfSKarsten Keil } 404960366cfSKarsten Keil /* calculate start and number of samples */ 405960366cfSKarsten Keil start = count % (*(pat->siz[index])); 406960366cfSKarsten Keil num = len; 407960366cfSKarsten Keil if (num+count > pat->seq[index]) 408960366cfSKarsten Keil num = pat->seq[index] - count; 409960366cfSKarsten Keil if (num+start > (*(pat->siz[index]))) 410960366cfSKarsten Keil num = (*(pat->siz[index])) - start; 411960366cfSKarsten Keil /* copy memory */ 412960366cfSKarsten Keil memcpy(data, pat->data[index]+start, num); 413960366cfSKarsten Keil /* reduce length */ 414960366cfSKarsten Keil data += num; 415960366cfSKarsten Keil count += num; 416960366cfSKarsten Keil len -= num; 417960366cfSKarsten Keil } 418960366cfSKarsten Keil tone->index = index; 419960366cfSKarsten Keil tone->count = count; 420960366cfSKarsten Keil 421960366cfSKarsten Keil /* return sk_buff */ 422960366cfSKarsten Keil return; 423960366cfSKarsten Keil } 424960366cfSKarsten Keil 425960366cfSKarsten Keil 426960366cfSKarsten Keil /******************************* 427960366cfSKarsten Keil * send HW message to hfc card * 428960366cfSKarsten Keil *******************************/ 429960366cfSKarsten Keil 430960366cfSKarsten Keil static void 431960366cfSKarsten Keil dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len) 432960366cfSKarsten Keil { 433960366cfSKarsten Keil struct sk_buff *nskb; 434960366cfSKarsten Keil 435960366cfSKarsten Keil /* unlocking is not required, because we don't expect a response */ 436960366cfSKarsten Keil nskb = _alloc_mISDN_skb(PH_CONTROL_REQ, 437960366cfSKarsten Keil (len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample, 438960366cfSKarsten Keil GFP_ATOMIC); 439960366cfSKarsten Keil if (nskb) { 440960366cfSKarsten Keil if (dsp->ch.peer) { 441960366cfSKarsten Keil if (dsp->ch.recv(dsp->ch.peer, nskb)) 442960366cfSKarsten Keil dev_kfree_skb(nskb); 443960366cfSKarsten Keil } else 444960366cfSKarsten Keil dev_kfree_skb(nskb); 445960366cfSKarsten Keil } 446960366cfSKarsten Keil } 447960366cfSKarsten Keil 448960366cfSKarsten Keil 449960366cfSKarsten Keil /***************** 450960366cfSKarsten Keil * timer expires * 451960366cfSKarsten Keil *****************/ 452960366cfSKarsten Keil void 453960366cfSKarsten Keil dsp_tone_timeout(void *arg) 454960366cfSKarsten Keil { 455960366cfSKarsten Keil struct dsp *dsp = arg; 456960366cfSKarsten Keil struct dsp_tone *tone = &dsp->tone; 457960366cfSKarsten Keil struct pattern *pat = (struct pattern *)tone->pattern; 458960366cfSKarsten Keil int index = tone->index; 459960366cfSKarsten Keil 460960366cfSKarsten Keil if (!tone->tone) 461960366cfSKarsten Keil return; 462960366cfSKarsten Keil 463960366cfSKarsten Keil index++; 464960366cfSKarsten Keil if (!pat->seq[index]) 465960366cfSKarsten Keil index = 0; 466960366cfSKarsten Keil tone->index = index; 467960366cfSKarsten Keil 468960366cfSKarsten Keil /* set next tone */ 469960366cfSKarsten Keil if (pat->data[index] == DATA_S) 470bcf91745SHannes Eder dsp_tone_hw_message(dsp, NULL, 0); 471960366cfSKarsten Keil else 472960366cfSKarsten Keil dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index])); 473960366cfSKarsten Keil /* set timer */ 474960366cfSKarsten Keil init_timer(&tone->tl); 475960366cfSKarsten Keil tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000; 476960366cfSKarsten Keil add_timer(&tone->tl); 477960366cfSKarsten Keil } 478960366cfSKarsten Keil 479960366cfSKarsten Keil 480960366cfSKarsten Keil /******************** 481960366cfSKarsten Keil * set/release tone * 482960366cfSKarsten Keil ********************/ 483960366cfSKarsten Keil 484960366cfSKarsten Keil /* 485960366cfSKarsten Keil * tones are relaized by streaming or by special loop commands if supported 486960366cfSKarsten Keil * by hardware. when hardware is used, the patterns will be controlled by 487960366cfSKarsten Keil * timers. 488960366cfSKarsten Keil */ 489960366cfSKarsten Keil int 490960366cfSKarsten Keil dsp_tone(struct dsp *dsp, int tone) 491960366cfSKarsten Keil { 492960366cfSKarsten Keil struct pattern *pat; 493960366cfSKarsten Keil int i; 494960366cfSKarsten Keil struct dsp_tone *tonet = &dsp->tone; 495960366cfSKarsten Keil 496960366cfSKarsten Keil tonet->software = 0; 497960366cfSKarsten Keil tonet->hardware = 0; 498960366cfSKarsten Keil 499960366cfSKarsten Keil /* we turn off the tone */ 500960366cfSKarsten Keil if (!tone) { 501960366cfSKarsten Keil if (dsp->features.hfc_loops) 502960366cfSKarsten Keil if (timer_pending(&tonet->tl)) 503960366cfSKarsten Keil del_timer(&tonet->tl); 504960366cfSKarsten Keil if (dsp->features.hfc_loops) 505960366cfSKarsten Keil dsp_tone_hw_message(dsp, NULL, 0); 506960366cfSKarsten Keil tonet->tone = 0; 507960366cfSKarsten Keil return 0; 508960366cfSKarsten Keil } 509960366cfSKarsten Keil 510960366cfSKarsten Keil pat = NULL; 511960366cfSKarsten Keil i = 0; 512960366cfSKarsten Keil while (pattern[i].tone) { 513960366cfSKarsten Keil if (pattern[i].tone == tone) { 514960366cfSKarsten Keil pat = &pattern[i]; 515960366cfSKarsten Keil break; 516960366cfSKarsten Keil } 517960366cfSKarsten Keil i++; 518960366cfSKarsten Keil } 519960366cfSKarsten Keil if (!pat) { 520960366cfSKarsten Keil printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone); 521960366cfSKarsten Keil return -EINVAL; 522960366cfSKarsten Keil } 523960366cfSKarsten Keil if (dsp_debug & DEBUG_DSP_TONE) 524960366cfSKarsten Keil printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n", 525960366cfSKarsten Keil __func__, tone, 0); 526960366cfSKarsten Keil tonet->tone = tone; 527960366cfSKarsten Keil tonet->pattern = pat; 528960366cfSKarsten Keil tonet->index = 0; 529960366cfSKarsten Keil tonet->count = 0; 530960366cfSKarsten Keil 531960366cfSKarsten Keil if (dsp->features.hfc_loops) { 532960366cfSKarsten Keil tonet->hardware = 1; 533960366cfSKarsten Keil /* set first tone */ 534960366cfSKarsten Keil dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0])); 535960366cfSKarsten Keil /* set timer */ 536960366cfSKarsten Keil if (timer_pending(&tonet->tl)) 537960366cfSKarsten Keil del_timer(&tonet->tl); 538960366cfSKarsten Keil init_timer(&tonet->tl); 539960366cfSKarsten Keil tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000; 540960366cfSKarsten Keil add_timer(&tonet->tl); 541960366cfSKarsten Keil } else { 542960366cfSKarsten Keil tonet->software = 1; 543960366cfSKarsten Keil } 544960366cfSKarsten Keil 545960366cfSKarsten Keil return 0; 546960366cfSKarsten Keil } 547960366cfSKarsten Keil 548960366cfSKarsten Keil 549960366cfSKarsten Keil 550960366cfSKarsten Keil 551960366cfSKarsten Keil 552