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