int voice_record(char *buf, int length, int codec) { gsm_signal input[160]; const char *pos = buf; int ramki_dwie; switch (codec) { case EKG_CODEC_NONE: ramki_dwie = 32 + 33; break; case EKG_CODEC_GSM: ramki_dwie = 33 + 33; break; default: /* przeczytaj cokolwiek, zeby nam petelka z select() * nie robila 100% CPU */ return read(voice_fd, input, 320); } while (pos <= (buf + length - ramki_dwie)) { if (read(voice_fd, input, 320) != 320) return -1; switch (codec) { case EKG_CODEC_NONE: pos += 32; break; case EKG_CODEC_GSM: gsm_encode(voice_gsm_enc, input, (unsigned char *) pos); pos += 33; break; } if (read(voice_fd, input, 320) != 320) return -1; switch (codec) { case EKG_CODEC_NONE: pos += 33; break; case EKG_CODEC_GSM: gsm_encode(voice_gsm_enc, input, (unsigned char *) pos); pos += 33; break; } } return 0; }
static int libgsm_encode_frame(AVCodecContext *avctx, unsigned char *frame, int buf_size, void *data) { // we need a full block if(buf_size < avctx->block_align) return 0; switch(avctx->codec_id) { case CODEC_ID_GSM: gsm_encode(avctx->priv_data,data,frame); break; case CODEC_ID_GSM_MS: gsm_encode(avctx->priv_data,data,frame); gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32); } return avctx->block_align; }
/*! \brief encode and produce a frame */ static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt) { struct gsm_translator_pvt *tmp = pvt->pvt; struct ast_frame *result = NULL; struct ast_frame *last = NULL; int samples = 0; /* output samples */ while (pvt->samples >= GSM_SAMPLES) { struct ast_frame *current; /* Encode a frame of data */ gsm_encode(tmp->gsm, tmp->buf + samples, (gsm_byte *) pvt->outbuf.c); samples += GSM_SAMPLES; pvt->samples -= GSM_SAMPLES; current = ast_trans_frameout(pvt, GSM_FRAME_LEN, GSM_SAMPLES); if (!current) { continue; } else if (last) { AST_LIST_NEXT(last, frame_list) = current; } else { result = current; } last = current; } /* Move the data at the end of the buffer to the front */ if (samples) { memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2); } return result; }
static int codec_encoder(const struct PluginCodec_Definition * codec, void * _context, const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned int * flag) { struct gsm_state * context = (struct gsm_state *)_context; int frames; if (*toLen < BYTES_PER_FRAME) return 0; if (*fromLen < SAMPLES_PER_FRAME * 2) return 0; frames = MIN(*fromLen / (SAMPLES_PER_FRAME * 2), (*toLen / BYTES_PER_FRAME)); if (frames == 0) return 0; *fromLen = frames * SAMPLES_PER_FRAME * 2; *toLen = frames * BYTES_PER_FRAME; while (frames-- > 0) { gsm_encode(context, (void *)from, to); to = ((char *)to) + BYTES_PER_FRAME; from = ((const char *)from) + SAMPLES_PER_FRAME * 2; } return 1; }
static int gsmflush(ft_t ft) { int r, ch, chans; gsm_signal *gbuff; struct gsmpriv *p = (struct gsmpriv *) ft->priv; chans = p->channels; /* zero-fill samples as needed */ while (p->samplePtr < p->sampleTop) *(p->samplePtr)++ = 0; gbuff = p->sampleTop; for (ch=0; ch<chans; ch++) { int i; gsm_signal *gsp; gsp = p->samples + ch; for (i=0; i<BLOCKSIZE; i++) { gbuff[i] = *gsp; gsp += chans; } gsm_encode(p->handle[ch], gbuff, p->frames); r = st_writebuf(ft, p->frames, FRAMESIZE, 1); if (r != 1) { st_fail_errno(ft,errno,"write error"); return(ST_EOF); } } p->samplePtr = p->samples; return (ST_SUCCESS); }
static struct ast_frame *lintogsm_frameout(struct ast_translator_pvt *tmp) { int x=0; /* We can't work on anything less than a frame in size */ if (tmp->tail < 160) return NULL; tmp->f.frametype = AST_FRAME_VOICE; tmp->f.subclass = AST_FORMAT_GSM; tmp->f.mallocd = 0; tmp->f.offset = AST_FRIENDLY_OFFSET; tmp->f.src = __PRETTY_FUNCTION__; tmp->f.data = tmp->outbuf; while(tmp->tail >= 160) { if ((x+1) * 33 >= sizeof(tmp->outbuf)) { ast_log(LOG_WARNING, "Out of buffer space\n"); break; } /* Encode a frame of data */ gsm_encode(tmp->gsm, tmp->buf, ((gsm_byte *) tmp->outbuf) + (x * 33)); /* Assume 8000 Hz -- 20 ms */ tmp->tail -= 160; /* Move the data at the end of the buffer to the front */ if (tmp->tail) memmove(tmp->buf, tmp->buf + 160, tmp->tail * 2); x++; } tmp->f.datalen = x * 33; tmp->f.samples = x * 160; return &tmp->f; }
SRef<Processing_Data_Rtp*> Gsm_Encoder_Instance::encode(const SRef<Processing_Data*>& data, uint16_t* seqNo, uint32_t ssrc) { SRef<Processing_Data_Audio*> adata = dynamic_cast<Processing_Data_Audio*>(*data); my_assert(adata); short resampledData[1600]; short* toEncode = adata->samples; if (adata->sfreq!=8000) { if (!resampler) resampler = Resampler_Registry::get_instance()->create( SOUND_CARD_FREQ, 8000, 20, 1 /*Nb channels */); resampler->resample( adata->samples, resampledData ); toEncode = &resampledData[0]; } int inSize = adata->nsamples*2; unsigned char outBuf[GSM_FRAME_SIZE]; if( inSize != GSM_EXEPECTED_INPUT * sizeof( short ) ) { return 0; } gsm_encode( gsmState, (gsm_signal *)toEncode, (gsm_byte *)outBuf ); *seqNo = *seqNo + 1; SRef<SRtp_Packet*> rtp = new SRtp_Packet(&outBuf[0], GSM_FRAME_SIZE, *seqNo, timestamp, ssrc); rtp->get_header().set_payload_type(/*rtpPayloadTypeNo*/ 3); SRef<Processing_Data_Rtp*> rdata = new Processing_Data_Rtp(rtp); return rdata; }
tsk_size_t tdav_codec_gsm_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size) { tsk_size_t out_size; tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self; if(!self || !in_data || !in_size || !out_data) { TSK_DEBUG_ERROR("Invalid parameter"); return 0; } out_size = ((in_size / (TMEDIA_CODEC_PCM_FRAME_SIZE(self) * sizeof(short))) * TDAV_GSM_FRAME_SIZE); /* allocate new buffer if needed */ if(*out_max_size <out_size) { if(!(*out_data = tsk_realloc(*out_data, out_size))) { TSK_DEBUG_ERROR("Failed to allocate new buffer"); *out_max_size = 0; return 0; } *out_max_size = out_size; } gsm_encode(gsm->encoder, (gsm_signal*)in_data, (gsm_byte*)*out_data); return out_size; }
CODEC_API int PLG_ENCODE_V1(libgsm)(void* handle, const void* pAudioBuffer, unsigned cbAudioSamples, int* rSamplesConsumed, void* pCodedData, unsigned cbMaxCodedData, int* pcbCodedSize, unsigned* pbSendNow) { struct libgsm_codec_data *mpGsm = (struct libgsm_codec_data *)handle; assert(handle != NULL); if (cbMaxCodedData < GSM_FRAME_BYTES) { return RPLG_INVALID_ARGUMENT; } memcpy(&mpGsm->mpBuffer[mpGsm->mBufferLoad], pAudioBuffer, SIZE_OF_SAMPLE*cbAudioSamples); mpGsm->mBufferLoad = mpGsm->mBufferLoad + cbAudioSamples; assert(mpGsm->mBufferLoad <= GSM_FRAME_SAMPLES); /* Check for necessary number of samples */ if (mpGsm->mBufferLoad == GSM_FRAME_SAMPLES) { gsm_encode(mpGsm->mpGsmState, (gsm_signal*)mpGsm->mpBuffer, (gsm_byte*)pCodedData); mpGsm->mBufferLoad = 0; *pcbCodedSize = GSM_FRAME_BYTES; *pbSendNow = TRUE; } else { *pcbCodedSize = 0; *pbSendNow = FALSE; } *rSamplesConsumed = cbAudioSamples; return RPLG_SUCCESS; }
static void enc_process(MSFilter *f){ EncState *s=(EncState*)f->data; mblk_t *im; unsigned int unitary_buff_size = sizeof(int16_t)*160; unsigned int buff_size = unitary_buff_size*s->ptime/20; int16_t* buff; int offset; while((im=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put(s->bufferizer,im); } while(ms_bufferizer_get_avail(s->bufferizer) >= buff_size) { mblk_t *om=allocb(33*s->ptime/20,0); buff = (int16_t *)alloca(buff_size); ms_bufferizer_read(s->bufferizer,(uint8_t*)buff,buff_size); for (offset=0;offset<buff_size;offset+=unitary_buff_size) { gsm_encode(s->state,(gsm_signal*)&buff[offset/sizeof(int16_t)],(gsm_byte*)om->b_wptr); om->b_wptr+=33; } mblk_set_timestamp_info(om,s->ts); ms_queue_put(f->outputs[0],om); s->ts+=buff_size/sizeof(int16_t)/*sizeof(buf)/2*/; } }
uint16 t_gsm_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, uint8 *payload, uint16 payload_size, bool &silence) { assert(payload_size >= _max_payload_size); silence = false; gsm_encode(gsm_encoder, sample_buf, payload); return _max_payload_size; }
static int libgsm_encode_frame(AVCodecContext *avctx, unsigned char *frame, int buf_size, void *data) { // we need a full block if(buf_size < GSM_BLOCK_SIZE) return 0; gsm_encode(avctx->priv_data,data,frame); return GSM_BLOCK_SIZE; }
static int encode_audio(struct mgcp_process_rtp_state *state, uint8_t *dst, size_t buf_size, size_t max_samples) { int nbytes = 0; size_t nsamples = 0; /* Encode samples into dst */ while (nsamples + state->dst_samples_per_frame <= max_samples) { if (nbytes + state->dst_frame_size > buf_size) { if (nbytes > 0) break; /* Not even one frame fits into the buffer */ LOGP(DMGCP, LOGL_INFO, "Encoding (RTP) buffer too small: %d > %d.\n", nbytes + state->dst_frame_size, buf_size); return -ENOSPC; } switch (state->dst_fmt) { case AF_GSM: gsm_encode(state->dst.gsm_handle, state->samples + state->sample_offs, dst); break; #ifdef HAVE_BCG729 case AF_G729: bcg729Encoder(state->dst.g729_enc, state->samples + state->sample_offs, dst); break; #endif case AF_PCMU: ulaw_encode(state->samples + state->sample_offs, dst, state->src_samples_per_frame); break; case AF_PCMA: alaw_encode(state->samples + state->sample_offs, dst, state->src_samples_per_frame); break; case AF_S16: memmove(dst, state->samples + state->sample_offs, state->dst_frame_size); break; case AF_L16: l16_encode(state->samples + state->sample_offs, dst, state->src_samples_per_frame); break; default: break; } dst += state->dst_frame_size; nbytes += state->dst_frame_size; state->sample_offs += state->dst_samples_per_frame; nsamples += state->dst_samples_per_frame; } state->sample_cnt -= nsamples; return nbytes; }
int GSMCodec::Encode (WORD *in,int inLen,BYTE* out,int outLen) { //Comprobamos las longitudes if ((inLen!=numFrameSamples) || (outLen<frameLength)) return 0; //Codificamos gsm_encode(g,(gsm_signal *)in,(gsm_byte *)out); return frameLength; }
static int wav_gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) { int k ; /* Encode the samples. */ gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ; gsm_encode (pgsm610->gsm_data, pgsm610->samples+GSM610_SAMPLES/2, pgsm610->block+GSM610_BLOCKSIZE/2) ; /* Write the block to disk. */ if ((k = fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf->file)) != GSM610_BLOCKSIZE) psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, GSM610_BLOCKSIZE) ; pgsm610->samplecount = 0 ; pgsm610->blockcount ++ ; /* Set samples to zero for next block. */ memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ; return 1 ; } /* wav_gsm610_write_block */
static int codec_msgsm_encoder(const struct PluginCodec_Definition * codec, void * _context, const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned int * flag) { struct gsm_state * context = (struct gsm_state *)_context; if (*fromLen < (MSGSM_SAMPLES_PER_FRAME*2) || *toLen < MSGSM_BYTES_PER_FRAME) return 0; gsm_encode(context, (short *)from, (unsigned char *)to); gsm_encode(context, ((short *)from)+160, ((unsigned char *)to)+32); *toLen = MSGSM_BYTES_PER_FRAME; return 1; }
static int libgsm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { int ret; gsm_signal *samples = (gsm_signal *)frame->data[0]; struct gsm_state *state = avctx->priv_data; if ((ret = ff_alloc_packet2(avctx, avpkt, avctx->block_align))) return ret; switch(avctx->codec_id) { case CODEC_ID_GSM: gsm_encode(state, samples, avpkt->data); break; case CODEC_ID_GSM_MS: gsm_encode(state, samples, avpkt->data); gsm_encode(state, samples + GSM_FRAME_SIZE, avpkt->data + 32); } *got_packet_ptr = 1; return 0; }
static int encode(struct auenc_state *st, uint8_t *buf, size_t *len, const int16_t *sampv, size_t sampc) { if (sampc != FRAME_SIZE) return EPROTO; if (*len < sizeof(gsm_frame)) return ENOMEM; gsm_encode(st->enc, (gsm_signal *)sampv, buf); *len = sizeof(gsm_frame); return 0; }
static int codec_encoder(const struct PluginCodec_Definition * codec, void * _context, const void * from, unsigned * fromLen, void * to, unsigned * toLen, unsigned int * flag) { struct gsm_state * context = (struct gsm_state *)_context; gsm_encode(context, (void *)from, to); *toLen = BYTES_PER_FRAME; return 1; }
static void enc_process(MSFilter *f){ EncState *s=(EncState*)f->data; mblk_t *im; int16_t buf[160]; while((im=ms_queue_get(f->inputs[0]))!=NULL){ ms_bufferizer_put(s->bufferizer,im); } while(ms_bufferizer_read(s->bufferizer,(uint8_t*)buf,sizeof(buf))==sizeof(buf)) { mblk_t *om=allocb(33,0); gsm_encode(s->state,(gsm_signal*)buf,(gsm_byte*)om->b_wptr); om->b_wptr+=33; mblk_set_timestamp_info(om,s->ts); ms_queue_put(f->outputs[0],om); s->ts+=sizeof(buf)/2; } }
static int encode(struct auenc_state *st, uint8_t *buf, size_t *len, int fmt, const void *sampv, size_t sampc) { if (sampc != FRAME_SIZE) return EPROTO; if (*len < sizeof(gsm_frame)) return ENOMEM; if (fmt != AUFMT_S16LE) return ENOTSUP; gsm_encode(st->enc, (gsm_signal *)sampv, buf); *len = sizeof(gsm_frame); return 0; }
int main(int argc, char** argv) { gsm gsmh; gsm_signal src[GSM_SAMPLE_BLOCK], dec[GSM_SAMPLE_BLOCK]; gsm_frame dst; const char* inFN; FILE* inFile; const char* encFN; FILE* encFile; const char* decFN; FILE* decFile; int n; /* For status dots */ if (4 != argc) fail ("Usage: testjms input encode decode"); inFN = argv[1]; inFile = mustOpen(inFN, "rb"); encFN = argv[2]; encFile = mustOpen(encFN, "wb"); decFN = argv[3]; decFile = mustOpen(decFN, "wb"); gsmh = gsm_create(); if (! gsmh) fail ("Can't create gsm\n"); while (fread(FP(src), inFile) == GSM_SAMPLE_BLOCK) { if ((n++) % 100) { (void) printf ("."); n = 0; } gsm_encode(gsmh, src, dst); fwrite(FP(dst), encFile); gsm_decode(gsmh, dst, dec); fwrite(FP(dec), decFile); } fclose (inFile); fclose (encFile); fclose (decFile); (void) puts ("\ndone"); return 0; }
static int pcm16_2_gsm(unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ) { int i; gsm* h_arr; div_t blocks; h_arr = (gsm*)h_codec; blocks = div(size,320); if(blocks.rem){ ERROR("pcm16_2_gsm: number of blocks should be integral (block size = 320)\n"); return -1; } for (i=0;i<blocks.quot;i++) gsm_encode(h_arr[0],(gsm_signal*)(in_buf + i*320),out_buf + i*33); return blocks.quot * 33; }
static GstFlowReturn gst_gsmenc_handle_frame (GstAudioEncoder * benc, GstBuffer * buffer) { GstGSMEnc *gsmenc; gsm_signal *data; GstFlowReturn ret = GST_FLOW_OK; GstBuffer *outbuf; GstMapInfo map, omap; gsmenc = GST_GSMENC (benc); /* we don't deal with squeezing remnants, so simply discard those */ if (G_UNLIKELY (buffer == NULL)) { GST_DEBUG_OBJECT (gsmenc, "no data"); goto done; } gst_buffer_map (buffer, &map, GST_MAP_READ); if (G_UNLIKELY (map.size < 320)) { GST_DEBUG_OBJECT (gsmenc, "discarding trailing data %d", (gint) map.size); gst_buffer_unmap (buffer, &map); ret = gst_audio_encoder_finish_frame (benc, NULL, -1); goto done; } outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte)); gst_buffer_map (outbuf, &omap, GST_MAP_WRITE); /* encode 160 16-bit samples into 33 bytes */ data = (gsm_signal *) map.data; gsm_encode (gsmenc->state, data, (gsm_byte *) omap.data); GST_LOG_OBJECT (gsmenc, "encoded to %d bytes", (gint) omap.size); gst_buffer_unmap (buffer, &map); gst_buffer_unmap (buffer, &omap); ret = gst_audio_encoder_finish_frame (benc, outbuf, 160); done: return ret; }
/*! \brief encode and produce a frame */ static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt) { struct gsm_translator_pvt *tmp = pvt->pvt; int datalen = 0; int samples = 0; /* We can't work on anything less than a frame in size */ if (pvt->samples < GSM_SAMPLES) return NULL; while (pvt->samples >= GSM_SAMPLES) { /* Encode a frame of data */ gsm_encode(tmp->gsm, tmp->buf, (gsm_byte *)pvt->outbuf + datalen); datalen += GSM_FRAME_LEN; samples += GSM_SAMPLES; pvt->samples -= GSM_SAMPLES; /* Move the data at the end of the buffer to the front */ if (pvt->samples) memmove(tmp->buf, tmp->buf + GSM_SAMPLES, pvt->samples * 2); } return ast_trans_frameout(pvt, datalen, samples); }
static GstFlowReturn gst_gsmenc_chain (GstPad * pad, GstBuffer * buf) { GstGSMEnc *gsmenc; gsm_signal *data; GstFlowReturn ret = GST_FLOW_OK; gsmenc = GST_GSMENC (gst_pad_get_parent (pad)); if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) { gst_adapter_clear (gsmenc->adapter); } gst_adapter_push (gsmenc->adapter, buf); while (gst_adapter_available (gsmenc->adapter) >= 320) { GstBuffer *outbuf; outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte)); GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts; GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND; gsmenc->next_ts += 20 * GST_MSECOND; /* encode 160 16-bit samples into 33 bytes */ data = (gsm_signal *) gst_adapter_peek (gsmenc->adapter, 320); gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf)); gst_adapter_flush (gsmenc->adapter, 320); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (gsmenc->srcpad)); GST_DEBUG_OBJECT (gsmenc, "Pushing buffer of size %d", GST_BUFFER_SIZE (outbuf)); ret = gst_pad_push (gsmenc->srcpad, outbuf); } gst_object_unref (gsmenc); return ret; }
int CallBackVmsSoundPCM(void * userData,sampleFrame *pcmBufferP,unsigned int *lengthP,Boolean recordB) { VmsPlayRecordType *vmsObjP; sampleFrame *tempP=0; sampleFrame *pcmP=0; //sampleFrame *pcmLoopP = 0; //int j; char audioBuff[150]; int index = 0; int i; int nsamples; nsamples = *lengthP; vmsObjP = (VmsPlayRecordType *)userData; if(vmsObjP) { if(vmsObjP->stopB) { StopAudio(vmsObjP->aqRecordPlayPcm,false); return 1; } pcmP = pcmBufferP; if(recordB) { if(*lengthP<640) { tempP = malloc(640*sizeof(sampleFrame)+4);//extra 4 byte memset(tempP,0,640*sizeof(sampleFrame)); memmove(tempP,pcmBufferP,*lengthP*sizeof(sampleFrame)); pcmP = tempP; nsamples = 640; } else { pcmP = pcmBufferP; } for ( i = 0; i < nsamples; i+= 160){ gsm_encode(vmsObjP->playRecordObj,(short*) pcmP + i, (gsm_byte *)(audioBuff + index)); index += 33; } fwrite(audioBuff,1,index,vmsObjP->playRecordFP); if(tempP) { free(tempP); } } else { memset(audioBuff,0,33*4); nsamples = fread(audioBuff,1,33*4,vmsObjP->playRecordFP); if(nsamples<33*4) { vmsObjP->stopB = true; } index = 0; for ( i = 0; i < nsamples; i+= 33){ gsm_decode(vmsObjP->playRecordObj,(gsm_byte *)(audioBuff + i),(short*) pcmP + index ); index += 160; } *lengthP = index; } } return 0; }
int main(int argc, char *argv[]) { int port; int netfd; int c, h=0, m, regm; FILE *f; int fd = STDIN_FILENO; char rcmd[RBUFSIZE]; fd_set readfd; fd_set writefd; struct timeval timer; struct timeval *timerptr = NULL; gsm_frame fo; load_options(); if (!strlen(callerid)) gethostname(callerid, sizeof(callerid)); signal(SIGHUP, sighandler); signal(SIGINT, sighandler); if ( !(f = fdopen(fd, "w+"))) { fprintf(stderr, "Unable to create file on fd %d\n", fd); return -1; } if ( (audiofd = audio_setup(audiodev)) == -1) { fprintf(stderr, "Fatal error: failed to open sound device"); return -1; } if ( (port = iax_init(0) < 0)) { fprintf(stderr, "Fatal error: failed to initialize iax with port %d\n", port); return -1; } iax_set_formats(AST_FORMAT_GSM); netfd = iax_get_fd(); check_iax_register(); fprintf(f, "Text Based Telephony Client.\n\n"); issue_prompt(f); timer.tv_sec = 0; timer.tv_usec = 0; while(1) { FD_ZERO(&readfd); FD_ZERO(&writefd); FD_SET(fd, &readfd); if(fd > h) h = fd; if(answered_call && !writeonly) { FD_SET(audiofd, &readfd); if(audiofd > h) h = audiofd; } if (cursound > -1) { FD_SET(audiofd, &writefd); if (audiofd > h) h = audiofd; } FD_SET(netfd, &readfd); if(netfd > h) h = netfd; if ( (c = select(h+1, &readfd, &writefd, 0, timerptr)) >= 0) { if(FD_ISSET(fd, &readfd)) { if ( ( fgets(&*rcmd, 256, f))) { rcmd[strlen(rcmd)-1] = 0; parse_args(f, &*rcmd); } else fprintf(f, "Fatal error: failed to read data!\n"); issue_prompt(f); } if(answered_call) { if(FD_ISSET(audiofd, &readfd)) { static int ret, rlen = 0; static short rbuf[FRAME_SIZE]; if ( (ret = read(audiofd, rbuf + rlen, 2 * (FRAME_SIZE-rlen))) == -1) { puts("Failed to read audio."); return -1; } rlen += ret/2; if(rlen == FRAME_SIZE) { rlen = 0; if(!most_recent_answer->gsmout) most_recent_answer->gsmout = gsm_create(); gsm_encode(most_recent_answer->gsmout, rbuf, fo); if(iax_send_voice(most_recent_answer->session, AST_FORMAT_GSM, (char *)fo, sizeof(fo)) == -1) puts("Failed to send voice!"); } } } do_iax_event(f); m = iax_time_to_next_event(); if(m > -1) { timerptr = &timer; timer.tv_sec = m /1000; timer.tv_usec = (m % 1000) * 1000; } else timerptr = 0; regm = check_iax_timeout(); if (!timerptr || (m > regm)) { timerptr = &timer; timer.tv_sec = regm /1000; timer.tv_usec = (regm % 1000) * 1000; } if (FD_ISSET(audiofd, &writefd)) { send_sound(audiofd); } } else { if(errno == EINTR) continue; fprintf(stderr, "Fatal error in select(): %s\n", strerror(errno)); return -1; } } return 0; }
int _v3_audio_encode( v3_handle v3h, /* pcm input */ const uint8_t *pcm, uint32_t pcmlen, /* payload output */ int16_t index, int16_t format, v3_coder *coder, uint8_t *data, uint32_t *datalen, /* optional args */ uint8_t channels) { uint32_t maxdatalen; int ret = V3_OK; _v3_enter(v3h, __func__); if (!pcm || !pcmlen || !coder || !data || !datalen || (datalen && !*datalen)) { _v3_leave(v3h, __func__); return V3_FAILURE; } maxdatalen = *datalen; *datalen = 0; channels = (channels == 2) ? 2 : 1; if (coder->state && (coder->index != index || coder->format != format)) { _v3_coder_destroy(v3h, coder); } switch (index) { #ifdef HAVE_GSM case 0: { const v3_codec *codec = v3_codec_get(index, format); int opt = 1; size_t ctr; _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to gsm @ %u", pcmlen, codec->rate); if (!coder->state) { if (!(coder->state = gsm_create())) { _v3_debug(v3h, V3_DBG_INFO, "failed to create gsm encoder"); ret = V3_FAILURE; break; } gsm_option(coder->state, GSM_OPT_WAV49, &opt); coder->index = index; coder->format = format; coder->encoder = true; } for (ctr = 0; ctr < pcmlen / codec->framesize && *datalen + 65 <= maxdatalen; ++ctr) { gsm_encode(coder->state, (void *)pcm, (void *)data); gsm_encode(coder->state, (void *)pcm+(codec->framesize/2), (void *)data+32); pcm += codec->framesize; data += 65; *datalen += 65; } } break; #endif #ifdef HAVE_OPUS case 1: case 2: { const v3_codec *codec = v3_codec_get(index, format); int tmp; _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to opus @ %u", pcmlen, codec->rate); if (!coder->state || channels != coder->channels) { if (coder->state) { opus_encoder_destroy(coder->state); coder->state = NULL; _v3_debug(v3h, V3_DBG_MEMORY, "released opus state"); } if (!(coder->state = opus_encoder_create(codec->rate, channels, OPUS_APPLICATION_AUDIO, &tmp))) { _v3_debug(v3h, V3_DBG_INFO, "failed to create opus encoder: %s", opus_strerror(tmp)); ret = V3_FAILURE; break; } if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_COMPLEXITY(10))) != OPUS_OK) { _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_COMPLEXITY: %s", opus_strerror(tmp)); opus_encoder_destroy(coder->state); coder->state = NULL; ret = V3_FAILURE; break; } if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_VBR(0))) != OPUS_OK) { _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_VBR: %s", opus_strerror(tmp)); opus_encoder_destroy(coder->state); coder->state = NULL; ret = V3_FAILURE; break; } if ((tmp = opus_encoder_ctl(coder->state, OPUS_SET_BITRATE(((index == 1) ? 79 : 43) * 1000))) != OPUS_OK) { _v3_debug(v3h, V3_DBG_INFO, "opus_encoder_ctl: OPUS_SET_BITRATE: %s", opus_strerror(tmp)); opus_encoder_destroy(coder->state); coder->state = NULL; ret = V3_FAILURE; break; } coder->index = index; coder->format = format; coder->channels = channels; coder->encoder = true; } maxdatalen = (maxdatalen <= ((index == 1) ? 198 : 108)) ? maxdatalen : ((index == 1) ? 198 : 108); if ((tmp = opus_encode(coder->state, (void *)pcm, codec->framesize / sizeof(int16_t), (void *)data, maxdatalen)) <= 0) { _v3_debug(v3h, V3_DBG_INFO, "failed to encode opus packet"); } *datalen = tmp; } break; #endif #ifdef HAVE_SPEEX case 3: { static const uint16_t maxspxbuf = 200; const v3_codec *codec = v3_codec_get(index, format); uint16_t framesize; SpeexBits bits; size_t ctr; _v3_debug(v3h, V3_DBG_INFO, "encoding %u bytes of pcm to speex @ %u", pcmlen, codec->rate); if (!coder->state) { switch (codec->rate) { case 8000: coder->state = speex_encoder_init(&speex_nb_mode); break; case 16000: coder->state = speex_encoder_init(&speex_wb_mode); break; case 32000: coder->state = speex_encoder_init(&speex_uwb_mode); break; } if (!coder->state) { _v3_debug(v3h, V3_DBG_INFO, "failed to create speex encoder"); ret = V3_FAILURE; break; } speex_encoder_ctl(coder->state, SPEEX_SET_QUALITY, (void *)&codec->quality); coder->index = index; coder->format = format; coder->encoder = true; } *(uint16_t *)data = htons(pcmlen / codec->framesize); data += sizeof(uint16_t); *datalen += sizeof(uint16_t); *(uint16_t *)data = htons(codec->framesize / sizeof(int16_t)); data += sizeof(uint16_t); *datalen += sizeof(uint16_t); speex_bits_init(&bits); for (ctr = 0; ctr < pcmlen / codec->framesize && *datalen + maxspxbuf <= maxdatalen; ++ctr) { speex_encode_int(coder->state, (void *)pcm, &bits); framesize = speex_bits_write(&bits, (void *)data + sizeof(uint16_t), maxspxbuf); speex_bits_reset(&bits); *(uint16_t *)data = htons(framesize); pcm += codec->framesize; data += sizeof(uint16_t) + framesize; *datalen += sizeof(uint16_t) + framesize; } speex_bits_destroy(&bits); } break; #endif default: (void)maxdatalen; _v3_debug(v3h, V3_DBG_INFO, "unsupported codec: index: %i | format: %i", index, format); ret = V3_FAILURE; break; } _v3_leave(v3h, __func__); return ret; }
int wr_gsm_encode(void * state, const short * input, char * output) { wr_gsm_state * sstate = (wr_gsm_state *)state; gsm_encode(sstate->handle, (gsm_signal*)input, (gsm_byte*)output); return 33; }