0001
0002
0003
0004
0005
0006
0007
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
0039
0040
0041
0042
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
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
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
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
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
0382 if (!tone->tone) {
0383 memset(data, dsp_silence, len);
0384 return;
0385 }
0386
0387
0388 pat = (struct pattern *)tone->pattern;
0389
0390 index = tone->index;
0391 count = tone->count;
0392
0393
0394 while (len) {
0395
0396 while (42) {
0397
0398 if (!pat->seq[index]) {
0399 count = 0;
0400 index = 0;
0401 }
0402
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
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
0419 memcpy(data, pat->data[index] + start, num);
0420
0421 data += num;
0422 count += num;
0423 len -= num;
0424 }
0425 tone->index = index;
0426 tone->count = count;
0427
0428
0429 return;
0430 }
0431
0432
0433
0434
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
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
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
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
0481 tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
0482 add_timer(&tone->tl);
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
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
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
0539 dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
0540
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 }