static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext) { /* Send a frame from the file to the appropriate channel */ struct wavg_desc *fs = (struct wavg_desc *)s->_private; s->fr.frametype = AST_FRAME_VOICE; ast_format_set(&s->fr.subclass.format, AST_FORMAT_GSM, 0); s->fr.offset = AST_FRIENDLY_OFFSET; s->fr.samples = GSM_SAMPLES; s->fr.mallocd = 0; AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE); if (fs->secondhalf) { /* Just return a frame based on the second GSM frame */ s->fr.data.ptr = (char *)s->fr.data.ptr + GSM_FRAME_SIZE; s->fr.offset += GSM_FRAME_SIZE; } else { /* read and convert */ unsigned char msdata[MSGSM_FRAME_SIZE]; int res; if ((res = fread(msdata, 1, MSGSM_FRAME_SIZE, s->f)) != MSGSM_FRAME_SIZE) { if (res && (res != 1)) ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); return NULL; } /* Convert from MS format to two real GSM frames */ conv65(msdata, s->fr.data.ptr); } fs->secondhalf = !fs->secondhalf; *whennext = GSM_SAMPLES; return &s->fr; }
static int gsm_write(struct ast_filestream *fs, struct ast_frame *f) { int res; unsigned char gsm[66]; if (f->frametype != AST_FRAME_VOICE) { ast_log(LOG_WARNING, "Asked to write non-voice frame!\n"); return -1; } if (f->subclass != AST_FORMAT_GSM) { ast_log(LOG_WARNING, "Asked to write non-GSM frame (%d)!\n", f->subclass); return -1; } if (!(f->datalen % 65)) { /* This is in MSGSM format, need to be converted */ int len=0; while(len < f->datalen) { conv65(f->data + len, gsm); if ((res = fwrite(gsm, 1, 66, fs->f)) != 66) { ast_log(LOG_WARNING, "Bad write (%d/66): %s\n", res, strerror(errno)); return -1; } len += 65; } } else { if (f->datalen % 33) { ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 33\n", f->datalen); return -1; } if ((res = fwrite(f->data, 1, f->datalen, fs->f)) != f->datalen) { ast_log(LOG_WARNING, "Bad write (%d/33): %s\n", res, strerror(errno)); return -1; } } return 0; }
static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext) { int res; char msdata[66]; /* Send a frame from the file to the appropriate channel */ s->fr.frametype = AST_FRAME_VOICE; s->fr.subclass = AST_FORMAT_GSM; s->fr.offset = AST_FRIENDLY_OFFSET; s->fr.samples = 160; s->fr.datalen = 33; s->fr.mallocd = 0; if (s->secondhalf) { /* Just return a frame based on the second GSM frame */ s->fr.data = s->gsm + 33; } else { if ((res = read(s->fd, msdata, 65)) != 65) { if (res && (res != 1)) ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno)); return NULL; } /* Convert from MS format to two real GSM frames */ conv65(msdata, s->gsm); s->fr.data = s->gsm; } s->secondhalf = !s->secondhalf; *whennext = 160; return &s->fr; }
static int gsm_write(struct ast_filestream *fs, struct ast_frame *f) { int res; unsigned char gsm[2*GSM_FRAME_SIZE]; if (!(f->datalen % 65)) { /* This is in MSGSM format, need to be converted */ int len=0; while(len < f->datalen) { conv65(f->data.ptr + len, gsm); if ((res = fwrite(gsm, 1, 2*GSM_FRAME_SIZE, fs->f)) != 2*GSM_FRAME_SIZE) { ast_log(LOG_WARNING, "Bad write (%d/66): %s\n", res, strerror(errno)); return -1; } len += 65; } } else { if (f->datalen % GSM_FRAME_SIZE) { ast_log(LOG_WARNING, "Invalid data length, %d, should be multiple of 33\n", f->datalen); return -1; } if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) { ast_log(LOG_WARNING, "Bad write (%d/33): %s\n", res, strerror(errno)); return -1; } } return 0; }
static int gsmtolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f) { /* Assuming there's space left, decode into the current buffer at the tail location. Read in as many frames as there are */ int x; unsigned char data[66]; int msgsm=0; if ((f->datalen % 33) && (f->datalen % 65)) { ast_log(LOG_WARNING, "Huh? A GSM frame that isn't a multiple of 33 or 65 bytes long from %s (%d)?\n", f->src, f->datalen); return -1; } if (f->datalen % 65 == 0) msgsm = 1; for (x=0;x<f->datalen;x+=(msgsm ? 65 : 33)) { if (msgsm) { /* Translate MSGSM format to Real GSM format before feeding in */ conv65(f->data + x, data); if (tmp->tail + 320 < sizeof(tmp->buf)/2) { if (gsm_decode(tmp->gsm, data, tmp->buf + tmp->tail)) { ast_log(LOG_WARNING, "Invalid GSM data (1)\n"); return -1; } tmp->tail+=160; if (gsm_decode(tmp->gsm, data + 33, tmp->buf + tmp->tail)) { ast_log(LOG_WARNING, "Invalid GSM data (2)\n"); return -1; } tmp->tail+=160; } else { ast_log(LOG_WARNING, "Out of (MS) buffer space\n"); return -1; } } else { if (tmp->tail + 160 < sizeof(tmp->buf)/2) { if (gsm_decode(tmp->gsm, f->data + x, tmp->buf + tmp->tail)) { ast_log(LOG_WARNING, "Invalid GSM data\n"); return -1; } tmp->tail+=160; } else { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } } } return 0; }
/*! \brief decode and store in outbuf. */ static int gsmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) { struct gsm_translator_pvt *tmp = pvt->pvt; int x; int16_t *dst = pvt->outbuf.i16; /* guess format from frame len. 65 for MSGSM, 33 for regular GSM */ int flen = (f->datalen % MSGSM_FRAME_LEN == 0) ? MSGSM_FRAME_LEN : GSM_FRAME_LEN; for (x=0; x < f->datalen; x += flen) { unsigned char data[2 * GSM_FRAME_LEN]; unsigned char *src; int len; if (flen == MSGSM_FRAME_LEN) { len = 2*GSM_SAMPLES; src = data; /* Translate MSGSM format to Real GSM format before feeding in */ /* XXX what's the point here! we should just work * on the full format. */ conv65(f->data.ptr + x, data); } else { len = GSM_SAMPLES; src = f->data.ptr + x; } /* XXX maybe we don't need to check */ if (pvt->samples + len > BUFFER_SAMPLES) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } if (gsm_decode(tmp->gsm, src, dst + pvt->samples)) { ast_log(LOG_WARNING, "Invalid GSM data (1)\n"); return -1; } pvt->samples += GSM_SAMPLES; pvt->datalen += 2 * GSM_SAMPLES; if (flen == MSGSM_FRAME_LEN) { if (gsm_decode(tmp->gsm, data + GSM_FRAME_LEN, dst + pvt->samples)) { ast_log(LOG_WARNING, "Invalid GSM data (2)\n"); return -1; } pvt->samples += GSM_SAMPLES; pvt->datalen += 2 * GSM_SAMPLES; } } return 0; }