static int celt_codec_encoder(const struct PluginCodec_Definition * codec, void * context, const void * fromPtr, unsigned * fromLen, void * toPtr, unsigned * toLen, unsigned int * flag) { CELTContext *celt = (CELTContext *)context; unsigned byteCount; if (*fromLen < codec->parm.audio.samplesPerFrame*sizeof(short)) return FALSE; if (*toLen < celt->bytes_per_packet) return FALSE; #ifdef HAVE_CELT_0_5_0_OR_LATER byteCount = celt_encode(celt->encoder_state, (celt_int16_t *)fromPtr, NULL, (char *)toPtr, celt->bytes_per_packet); #else byteCount = celt_encode(celt->encoder_state, (celt_int16_t *)fromPtr, (char *)toPtr, celt->bytes_per_packet); #endif if (byteCount < 0) { return 0; } *toLen = byteCount; *fromLen = codec->parm.audio.samplesPerFrame*sizeof(short); return TRUE; }
static switch_status_t switch_celt_encode(switch_codec_t *codec, switch_codec_t *other_codec, void *decoded_data, uint32_t decoded_data_len, uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag) { struct celt_context *context = codec->private_info; int bytes = 0; if (!context) { return SWITCH_STATUS_FALSE; } bytes = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, (unsigned char *) encoded_data, context->bytes_per_packet); if (bytes > 0) { *encoded_data_len = (uint32_t) bytes; return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error!\n"); return SWITCH_STATUS_GENERR; }
static int encode_frame(struct aucodec_st *st, uint16_t *size, uint8_t *buf, struct mbuf *src) { int len; /* NOTE: PCM audio in signed 16-bit format (native endian) */ len = celt_encode(st->enc, (short *)mbuf_buf(src), st->frame_size, buf, st->bytes_per_packet); if (len < 0) { DEBUG_WARNING("celt_encode: returned %d\n", len); return EINVAL; } DEBUG_INFO("encode: %u -> %d\n", mbuf_get_left(src), len); *size = len; mbuf_advance(src, st->fsize); return 0; }
SWIGEXPORT jint JNICALL Java_com_morlunk_jumble_audio_celt11_CELT11JNI_celt_1encode(JNIEnv *jenv, jclass jcls, jlong jarg1, jshortArray jarg2, jint jarg3, jbyteArray jarg4, jint jarg5) { jint jresult = 0 ; CELTEncoder *arg1 = (CELTEncoder *) 0 ; celt_int16 *arg2 = (celt_int16 *) 0 ; int arg3 ; unsigned char *arg4 = (unsigned char *) 0 ; int arg5 ; int result; (void)jenv; (void)jcls; arg1 = *(CELTEncoder **)&jarg1; { if (!jarg2) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg2) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg2 = (celt_int16 *) (*jenv)->GetShortArrayElements(jenv, jarg2, 0); } arg3 = (int)jarg3; { arg4 = (char *) (*jenv)->GetByteArrayElements(jenv, jarg4, 0); } arg5 = (int)jarg5; result = (int)celt_encode(arg1,(short const *)arg2,arg3,arg4,arg5); jresult = (jint)result; { (*jenv)->ReleaseShortArrayElements(jenv, jarg2, (jshort *)arg2, 0); } { (*jenv)->ReleaseByteArrayElements(jenv, jarg4, (jbyte *) arg4, 0); } return jresult; }
int main(void) { int current, pos; celt_int16 * sample_buffer; unsigned char * encoded_buffer; double * out_buffer; int sample_rate; int sample_bits; int sample_channels; int sample_buffer_size; int sample; int sample_msec; int sample_size; FILE * fd; int j, k; uint32_t frames; // FIXME! 4 byte! uint64_t start; struct sockaddr_in si_other; int s, i, slen=sizeof(si_other); char buf[BUFLEN]; CELTMode * cm; CELTEncoder * ce; int * error; int compressed; int jitter = 0; int64_t t; //struct cs * packets; double dr = 0, de = 0; srand(time(NULL)); if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) diep("socket"); memset((char *) &si_other, 0, sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons(PORT); if (inet_aton(SRV_IP, &si_other.sin_addr)==0) { fprintf(stderr, "inet_aton() failed\n"); exit(1); } fd = fopen("else.wav", "rb"); fseek(fd, 40, SEEK_SET); fread(&frames, sizeof(uint64_t), 1, fd); frames = 800000000; printf("%d\n", frames); // Hardcoded parameters for DSP sample_rate = 44100; // Desc. frequency, Hz sample_bits = 16; // Bits per sample sample_channels = 2; // Stereo // sample_msec = 10; // Size of sample, 100 ms for 10 Hz FFT freq. resolution sample_size = 1024; //sample_size = (int)(sample_rate * (sample_msec / 1000.0F)); sample_buffer_size = sample_size * sample_bits/8 * sample_channels; sample_buffer = (celt_int16 *) calloc(sample_buffer_size, sizeof(char)); encoded_buffer = (unsigned char *) calloc(sample_buffer_size, sizeof(char)); out_buffer = (double *) calloc(sample_buffer_size / (sample_bits/8), sizeof(double)); cm = celt_mode_create(sample_rate, sample_size, NULL); //printf("1\n"); ce = celt_encoder_create(cm, sample_channels, NULL); celt_encoder_ctl(ce, CELT_SET_COMPLEXITY(10)); celt_encoder_ctl(ce, CELT_SET_PREDICTION(2)); celt_encoder_ctl(ce, CELT_SET_VBR_RATE(120000)); for (i = 0; i < 5000; ++i) { read_sample_into_buffer(fd, (char *)sample_buffer, sample_size); printf("%d %d \n", (sample_rate / sample_size) * (frames / (sample_rate * sample_channels * (sample_bits / 8))) , i); printf("Sample_buffer_size: %d\n", sample_buffer_size); compressed = celt_encode(ce, sample_buffer, NULL, encoded_buffer, 1024); printf("Compressed bytes: %d, bitrate: %d kbps\n", compressed, (int)((sample_rate * sample_bits * sample_channels / 1024) * (compressed * 1.0F / sample_buffer_size))); *((uint16_t *)packets[i].data) = compressed; memcpy((char *)(packets[i].data + 2), encoded_buffer, compressed); packets[i].length = compressed; } for (i = 0; i < (sample_rate / sample_size) * (frames / (sample_rate * sample_channels * (sample_bits / 8))); ++i) { start = getcount(); printf("Sending packet %d\n", i); if (sendto(s, packets[i].data, packets[i].length, 0, &si_other, slen) == -1) diep("sendto()"); usleep(sample_size * 1000000 / sample_rate + jitter); //usleep(sample_size * 950000 / sample_rate); printf("Planned time: %.2f ms, real time: %.2f ms, needed time: %.2f\n", (sample_size * 1000000 / sample_rate + jitter) / 1000.0F, (getcount() - start) / 1000.0F, (sample_size * 1000000 / sample_rate) / 1000.0F); dr += (getcount() - start) / 1000.0F; de += (sample_size * 1000000 / sample_rate) / 1000.0F; if ((abs(t = ((sample_size * 1000000 / sample_rate) - (getcount() - start))) > (int)(1E-4 * (sample_size * 1000000 / sample_rate) )) ){//|| (fabs(dr - de) > 1E-6 * de)) { if (t > 0 || (de > dr)) { jitter += 1; printf("Sending packes too fast, increasing jitter: %d\n", jitter); } else { jitter -= 1; printf("Sending packes too slow, decreasing jitter: %d\n", jitter); } } //else// { //jitter = 0; //} } close(s); return 0; }
int main(int argc, char **argv) { int nb_samples, total_samples=0, nb_encoded; int c; int option_index = 0; char *inFile, *outFile; FILE *fin, *fout; short input[MAX_FRAME_SIZE]; celt_int32 frame_size = 960; int quiet=0; int nbBytes; CELTMode *mode; void *st; unsigned char bits[MAX_FRAME_BYTES]; int with_cbr = 0; int with_cvbr = 0; int with_skeleton = 0; int total_bytes = 0; int peak_bytes = 0; struct option long_options[] = { {"bitrate", required_argument, NULL, 0}, {"cbr",no_argument,NULL, 0}, {"cvbr",no_argument,NULL, 0}, {"comp", required_argument, NULL, 0}, {"nopf", no_argument, NULL, 0}, {"independent", no_argument, NULL, 0}, {"framesize", required_argument, NULL, 0}, {"skeleton",no_argument,NULL, 0}, {"help", no_argument, NULL, 0}, {"quiet", no_argument, NULL, 0}, {"le", no_argument, NULL, 0}, {"be", no_argument, NULL, 0}, {"8bit", no_argument, NULL, 0}, {"16bit", no_argument, NULL, 0}, {"mono", no_argument, NULL, 0}, {"stereo", no_argument, NULL, 0}, {"rate", required_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {"version-short", no_argument, NULL, 0}, {"comment", required_argument, NULL, 0}, {"author", required_argument, NULL, 0}, {"title", required_argument, NULL, 0}, {0, 0, 0, 0} }; int print_bitrate=0; celt_int32 rate=48000; celt_int32 size; int chan=1; int fmt=16; int lsb=1; ogg_stream_state os; ogg_stream_state so; /* ogg stream for skeleton bitstream */ ogg_page og; ogg_packet op; int bytes_written=0, ret, result; int id=-1; CELTHeader header; char vendor_string[64]; char *comments; int comments_length; int close_in=0, close_out=0; int eos=0; float bitrate=-1; char first_bytes[12]; int wave_input=0; celt_int32 lookahead = 0; int bytes_per_packet=-1; int complexity=-127; int prediction=2; /*Process command-line options*/ while(1) { c = getopt_long (argc, argv, "hvV", long_options, &option_index); if (c==-1) break; switch(c) { case 0: if (strcmp(long_options[option_index].name,"bitrate")==0) { bitrate = atof (optarg); } else if (strcmp(long_options[option_index].name,"cbr")==0) { with_cbr=1; } else if (strcmp(long_options[option_index].name,"cvbr")==0) { with_cvbr=1; } else if (strcmp(long_options[option_index].name,"skeleton")==0) { with_skeleton=1; } else if (strcmp(long_options[option_index].name,"help")==0) { usage(); exit(0); } else if (strcmp(long_options[option_index].name,"quiet")==0) { quiet = 1; } else if (strcmp(long_options[option_index].name,"version")==0) { version(); exit(0); } else if (strcmp(long_options[option_index].name,"version-short")==0) { version_short(); exit(0); } else if (strcmp(long_options[option_index].name,"le")==0) { lsb=1; } else if (strcmp(long_options[option_index].name,"be")==0) { lsb=0; } else if (strcmp(long_options[option_index].name,"8bit")==0) { fmt=8; } else if (strcmp(long_options[option_index].name,"16bit")==0) { fmt=16; } else if (strcmp(long_options[option_index].name,"stereo")==0) { chan=2; } else if (strcmp(long_options[option_index].name,"mono")==0) { chan=1; } else if (strcmp(long_options[option_index].name,"rate")==0) { rate=atoi (optarg); } else if (strcmp(long_options[option_index].name,"comp")==0) { complexity=atoi (optarg); } else if (strcmp(long_options[option_index].name,"framesize")==0) { frame_size=atoi (optarg); } else if (strcmp(long_options[option_index].name,"nopf")==0) { if (prediction>1) prediction=1; } else if (strcmp(long_options[option_index].name,"independent")==0) { prediction=0; } else if (strcmp(long_options[option_index].name,"comment")==0) { if (!strchr(optarg, '=')) { fprintf (stderr, "Invalid comment: %s\n", optarg); fprintf (stderr, "Comments must be of the form name=value\n"); exit(1); } comment_add(&comments, &comments_length, NULL, optarg); } else if (strcmp(long_options[option_index].name,"author")==0) { comment_add(&comments, &comments_length, "author=", optarg); } else if (strcmp(long_options[option_index].name,"title")==0) { comment_add(&comments, &comments_length, "title=", optarg); } break; case 'h': usage(); exit(0); break; case 'v': version(); exit(0); break; case 'V': print_bitrate=1; break; case '?': usage(); exit(1); break; } } if (argc-optind!=2) { usage(); exit(1); } inFile=argv[optind]; outFile=argv[optind+1]; /*Initialize Ogg stream struct*/ srand(time(NULL)); if (ogg_stream_init(&os, rand())==-1) { fprintf(stderr,"Error: stream init failed\n"); exit(1); } if (with_skeleton && ogg_stream_init(&so, rand())==-1) { fprintf(stderr,"Error: stream init failed\n"); exit(1); } if (strcmp(inFile, "-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdin), _O_BINARY); #elif defined OS2 _fsetmode(stdin,"b"); #endif fin=stdin; } else { fin = fopen(inFile, "rb"); if (!fin) { perror(inFile); exit(1); } close_in=1; } { fread(first_bytes, 1, 12, fin); if (strncmp(first_bytes,"RIFF",4)==0 && strncmp(first_bytes,"RIFF",4)==0) { if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1) exit(1); wave_input=1; lsb=1; /* CHECK: exists big-endian .wav ?? */ } } if (bitrate<=0.005) if (chan==1) bitrate=64.0; else bitrate=128.0; bytes_per_packet = MAX_FRAME_BYTES; mode = celt_mode_create(rate, frame_size, NULL); if (!mode) return 1; snprintf(vendor_string, sizeof(vendor_string), "Encoded with CELT %s\n",CELT_VERSION); comment_init(&comments, &comments_length, vendor_string); /*celt_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size);*/ celt_header_init(&header, mode, frame_size, chan); header.nb_channels = chan; { char *st_string="mono"; if (chan==2) st_string="stereo"; if (!quiet) if (with_cbr) fprintf (stderr, "Encoding %.0f kHz %s audio in %.0fms packets at %0.3fkbit/sec (%d bytes per packet, CBR)\n", header.sample_rate/1000., st_string, frame_size/(float)header.sample_rate*1000., bitrate, bytes_per_packet); else fprintf (stderr, "Encoding %.0f kHz %s audio in %.0fms packets at %0.3fkbit/sec (%d bytes per packet maximum)\n", header.sample_rate/1000., st_string, frame_size/(float)header.sample_rate*1000., bitrate, bytes_per_packet); } /*Initialize CELT encoder*/ st = celt_encoder_create_custom(mode, chan, NULL); { int tmp = (bitrate*1000); if (celt_encoder_ctl(st, CELT_SET_BITRATE(tmp)) != CELT_OK) { fprintf (stderr, "bitrate request failed\n"); return 1; } } if (!with_cbr) { if (celt_encoder_ctl(st, CELT_SET_VBR(1)) != CELT_OK) { fprintf (stderr, "VBR request failed\n"); return 1; } if (!with_cvbr) { if (celt_encoder_ctl(st, CELT_SET_VBR_CONSTRAINT(0)) != CELT_OK) { fprintf (stderr, "VBR constraint failed\n"); return 1; } } } if (celt_encoder_ctl(st, CELT_SET_PREDICTION(prediction)) != CELT_OK) { fprintf (stderr, "Prediction request failed\n"); return 1; } if (complexity!=-127) { if (celt_encoder_ctl(st, CELT_SET_COMPLEXITY(complexity)) != CELT_OK) { fprintf (stderr, "Only complexity 0 through 10 is supported\n"); return 1; } } if (strcmp(outFile,"-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdout), _O_BINARY); #endif fout=stdout; } else { fout = fopen(outFile, "wb"); if (!fout) { perror(outFile); exit(1); } close_out=1; } if (with_skeleton) { fprintf (stderr, "Warning: Enabling skeleton output may cause some decoders to fail.\n"); } /* first packet should be the skeleton header. */ if (with_skeleton) { add_fishead_packet(&so); if ((ret = flush_ogg_stream_to_file(&so, fout))) { fprintf (stderr,"Error: failed skeleton (fishead) header to output stream\n"); exit(1); } else bytes_written += ret; } /*Write header*/ { unsigned char header_data[100]; int packet_size = celt_header_to_packet(&header, header_data, 100); op.packet = header_data; op.bytes = packet_size; op.b_o_s = 1; op.e_o_s = 0; op.granulepos = 0; op.packetno = 0; ogg_stream_packetin(&os, &op); while((result = ogg_stream_flush(&os, &og))) { if(!result) break; ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } op.packet = (unsigned char *)comments; op.bytes = comments_length; op.b_o_s = 0; op.e_o_s = 0; op.granulepos = 0; op.packetno = 1; ogg_stream_packetin(&os, &op); } /* fisbone packet should be write after all bos pages */ if (with_skeleton) { add_fisbone_packet(&so, os.serialno, &header); if ((ret = flush_ogg_stream_to_file(&so, fout))) { fprintf (stderr,"Error: failed writing skeleton (fisbone )header to output stream\n"); exit(1); } else bytes_written += ret; } /* writing the rest of the celt header packets */ while((result = ogg_stream_flush(&os, &og))) { if(!result) break; ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } free(comments); /* write the skeleton eos packet */ if (with_skeleton) { add_eos_packet_to_stream(&so); if ((ret = flush_ogg_stream_to_file(&so, fout))) { fprintf (stderr,"Error: failed writing skeleton header to output stream\n"); exit(1); } else bytes_written += ret; } if (!wave_input) { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL); } else { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size); } if (nb_samples==0) eos=1; total_samples += nb_samples; nb_encoded = -lookahead; /*Main encoding loop (one frame per iteration)*/ while (!eos || total_samples>nb_encoded) { id++; /*Encode current frame*/ nbBytes = celt_encode(st, input, frame_size, bits, bytes_per_packet); if (nbBytes<0) { fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes); break; } nb_encoded += frame_size; total_bytes += nbBytes; peak_bytes=IMAX(nbBytes,peak_bytes); if (wave_input) { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size); } else { nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL); } if (nb_samples==0) { eos=1; } if (eos && total_samples<=nb_encoded) op.e_o_s = 1; else op.e_o_s = 0; total_samples += nb_samples; op.packet = (unsigned char *)bits; op.bytes = nbBytes; op.b_o_s = 0; /*Is this redundent?*/ if (eos && total_samples<=nb_encoded) op.e_o_s = 1; else op.e_o_s = 0; op.granulepos = (id+1)*frame_size-lookahead; if (op.granulepos>total_samples) op.granulepos = total_samples; /*printf ("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, nframes, lookahead, 5, 6);*/ op.packetno = 2+id; ogg_stream_packetin(&os, &op); /*Write all new pages (most likely 0 or 1)*/ while (ogg_stream_pageout(&os,&og)) { ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } } /*Flush all pages left to be written*/ while (ogg_stream_flush(&os, &og)) { ret = oe_write_page(&og, fout); if(ret != og.header_len + og.body_len) { fprintf (stderr,"Error: failed writing header to output stream\n"); exit(1); } else bytes_written += ret; } if (!with_cbr && !quiet) fprintf (stderr, "Average rate %0.3fkbit/sec, %d peak bytes per packet\n", (total_bytes*8.0/((float)nb_encoded/header.sample_rate))/1000.0, peak_bytes); celt_encoder_destroy(st); celt_mode_destroy(mode); ogg_stream_clear(&os); if (close_in) fclose(fin); if (close_out) fclose(fout); return 0; }
int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, unsigned char *data, int max_data_bytes) { void *silk_enc; CELTEncoder *celt_enc; int i; int ret=0; SKP_int32 nBytes; ec_enc enc; int framerate, period; int silk_internal_bandwidth=-1; int bytes_target; int prefill=0; int start_band = 0; int redundancy = 0; int redundancy_bytes = 0; int celt_to_silk = 0; /* TODO: This is 60 only so we can handle 60ms speech/audio switching it shouldn't bee too hard to reduce to 20 ms if needed */ short pcm_buf[60*48*2]; int nb_compr_bytes; int to_celt = 0; celt_int32 mono_rate; silk_enc = (char*)st+st->silk_enc_offset; celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); if (st->user_bitrate_bps==OPUS_BITRATE_AUTO) st->bitrate_bps = 60*st->Fs/frame_size + st->Fs*st->channels; else st->bitrate_bps = st->user_bitrate_bps; /* Rate-dependent mono-stereo decision */ if (st->mode == MODE_CELT_ONLY && st->channels == 2) { celt_int32 decision_rate; decision_rate = st->bitrate_bps + st->voice_ratio*st->voice_ratio; /* Add some hysteresis */ if (st->stream_channels == 2) decision_rate += 4000; else decision_rate -= 4000; if (decision_rate>48000) st->stream_channels = 2; else st->stream_channels = 1; } /* Equivalent bit-rate for mono */ mono_rate = st->bitrate_bps; if (st->stream_channels==2) mono_rate = (mono_rate+10000)/2; /* Compensate for smaller frame sizes assuming an equivalent overhead of 60 bits/frame */ mono_rate -= 60*(st->Fs/frame_size - 50); /* Mode selection */ if (st->user_mode==OPUS_MODE_AUTO) { celt_int32 decision_rate; /* SILK/CELT threshold is higher for voice than for music */ decision_rate = mono_rate - 3*st->voice_ratio*st->voice_ratio; /* Hysteresis */ if (st->prev_mode == MODE_CELT_ONLY) decision_rate += 4000; else if (st->prev_mode>0) decision_rate -= 4000; if (decision_rate>24000) st->mode = MODE_CELT_ONLY; else st->mode = MODE_SILK_ONLY; } else if (st->user_mode==OPUS_MODE_VOICE) { st->mode = MODE_SILK_ONLY; } else {/* OPUS_AUDIO_MODE */ st->mode = MODE_CELT_ONLY; } /* Automatic (rate-dependent) bandwidth selection */ if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch) { const int *bandwidth_thresholds; int bandwidth = BANDWIDTH_FULLBAND; bandwidth_thresholds = st->mode == MODE_CELT_ONLY ? audio_bandwidth_thresholds : voice_bandwidth_thresholds; do { int threshold, hysteresis; threshold = bandwidth_thresholds[2*(bandwidth-BANDWIDTH_MEDIUMBAND)]; hysteresis = bandwidth_thresholds[2*(bandwidth-BANDWIDTH_MEDIUMBAND)+1]; if (!st->first) { if (st->bandwidth >= bandwidth) threshold -= hysteresis; else threshold += hysteresis; } if (mono_rate >= threshold) break; } while (--bandwidth>BANDWIDTH_NARROWBAND); st->bandwidth = bandwidth; /* Prevents any transition to SWB/FB until the SILK layer has fully switched to WB mode and turned the variable LP filter off */ if (st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > BANDWIDTH_WIDEBAND) st->bandwidth = BANDWIDTH_WIDEBAND; } /* Prevents Opus from wasting bits on frequencies that are above the Nyquist rate of the input signal */ if (st->Fs <= 24000 && st->bandwidth > BANDWIDTH_SUPERWIDEBAND) st->bandwidth = BANDWIDTH_SUPERWIDEBAND; if (st->Fs <= 16000 && st->bandwidth > BANDWIDTH_WIDEBAND) st->bandwidth = BANDWIDTH_WIDEBAND; if (st->Fs <= 12000 && st->bandwidth > BANDWIDTH_MEDIUMBAND) st->bandwidth = BANDWIDTH_MEDIUMBAND; if (st->Fs <= 8000 && st->bandwidth > BANDWIDTH_NARROWBAND) st->bandwidth = BANDWIDTH_NARROWBAND; if (st->user_bandwidth != BANDWIDTH_AUTO) st->bandwidth = st->user_bandwidth; /* Prevents nonsensical configurations, i.e. modes that don't exist */ if (frame_size < st->Fs/100 && st->mode != MODE_CELT_ONLY) st->mode = MODE_CELT_ONLY; if (frame_size > st->Fs/50 && st->mode != MODE_SILK_ONLY) st->mode = MODE_SILK_ONLY; if (st->mode == MODE_CELT_ONLY && st->bandwidth == BANDWIDTH_MEDIUMBAND) st->bandwidth = BANDWIDTH_WIDEBAND; if (st->mode == MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND) st->mode = MODE_HYBRID; if (st->mode == MODE_HYBRID && st->bandwidth <= BANDWIDTH_WIDEBAND) st->mode = MODE_SILK_ONLY; bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1; data += 1; if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) { silk_EncControlStruct dummy; silk_InitEncoder( st->silk_enc, &dummy); prefill=1; } if (st->prev_mode > 0 && ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) || (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY))) { redundancy = 1; celt_to_silk = (st->mode != MODE_CELT_ONLY); if (!celt_to_silk) { /* Switch to SILK/hybrid if frame size is 10 ms or more*/ if (frame_size >= st->Fs/100) { st->mode = st->prev_mode; to_celt = 1; } else { redundancy=0; } } } ec_enc_init(&enc, data, max_data_bytes-1); /* SILK processing */ if (st->mode != MODE_CELT_ONLY) { st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size; if( st->mode == MODE_HYBRID ) { st->silk_mode.bitRate /= st->stream_channels; if( st->bandwidth == BANDWIDTH_SUPERWIDEBAND ) { if( st->Fs == 100 * frame_size ) { /* 24 kHz, 10 ms */ st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3; } else { /* 24 kHz, 20 ms */ st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3; } } else { if( st->Fs == 100 * frame_size ) { /* 48 kHz, 10 ms */ st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2; } else { /* 48 kHz, 20 ms */ st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2; } } st->silk_mode.bitRate *= st->stream_channels; /* don't let SILK use more than 80% */ if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) { st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5; } } st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; st->silk_mode.nChannelsAPI = st->channels; st->silk_mode.nChannelsInternal = st->stream_channels; if (st->bandwidth == BANDWIDTH_NARROWBAND) { st->silk_mode.desiredInternalSampleRate = 8000; } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) { st->silk_mode.desiredInternalSampleRate = 12000; } else { SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND ); st->silk_mode.desiredInternalSampleRate = 16000; } if( st->mode == MODE_HYBRID ) { /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */ st->silk_mode.minInternalSampleRate = 16000; } else { st->silk_mode.minInternalSampleRate = 8000; } st->silk_mode.maxInternalSampleRate = 16000; /* Call SILK encoder for the low band */ nBytes = max_data_bytes-1; if (prefill) { int zero=0; silk_Encode( silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 ); } ret = silk_Encode( silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 ); if( ret ) { fprintf (stderr, "SILK encode error: %d\n", ret); /* Handle error */ } if (nBytes==0) return 0; /* Extract SILK internal bandwidth for signaling in first byte */ if( st->mode == MODE_SILK_ONLY ) { if( st->silk_mode.internalSampleRate == 8000 ) { silk_internal_bandwidth = BANDWIDTH_NARROWBAND; } else if( st->silk_mode.internalSampleRate == 12000 ) { silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND; } else if( st->silk_mode.internalSampleRate == 16000 ) { silk_internal_bandwidth = BANDWIDTH_WIDEBAND; } } else { SKP_assert( st->silk_mode.internalSampleRate == 16000 ); } } /* CELT processing */ { int endband=21; switch(st->bandwidth) { case BANDWIDTH_NARROWBAND: endband = 13; break; case BANDWIDTH_WIDEBAND: endband = 17; break; case BANDWIDTH_SUPERWIDEBAND: endband = 19; break; case BANDWIDTH_FULLBAND: endband = 21; break; } celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband)); celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels)); } if (st->mode != MODE_SILK_ONLY) { celt_encoder_ctl(celt_enc, CELT_SET_VBR(0)); celt_encoder_ctl(celt_enc, CELT_SET_BITRATE(510000)); if (st->prev_mode == MODE_SILK_ONLY) { unsigned char dummy[10]; celt_encoder_ctl(celt_enc, CELT_RESET_STATE); celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); /* TODO: This wastes CPU a bit compared to just prefilling the buffer */ celt_encode(celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10); } else { celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2)); } if (st->mode == MODE_HYBRID) { int len; len = (ec_tell(&enc)+7)>>3; if( st->use_vbr ) { nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs); } else { /* check if SILK used up too much */ nb_compr_bytes = len > bytes_target ? len : bytes_target; } } else {
static GstFlowReturn gst_celt_enc_encode (GstCeltEnc * enc, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; gint frame_size = enc->frame_size; gint bytes = frame_size * 2 * enc->channels; gint bytes_per_packet; gint16 *data, *data0 = NULL; gint outsize, size; GstBuffer *outbuf; if (G_LIKELY (buf)) { data = (gint16 *) GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); if (G_UNLIKELY (size % bytes)) { GST_DEBUG_OBJECT (enc, "draining; adding silence samples"); size = ((size / bytes) + 1) * bytes; data0 = data = g_malloc0 (size); memcpy (data, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); } } else { GST_DEBUG_OBJECT (enc, "nothing to drain"); goto done; } frame_size = size / (2 * enc->channels); if (enc->cbr) { bytes_per_packet = (enc->bitrate * frame_size / enc->rate + 4) / 8; } else { bytes_per_packet = (enc->max_bitrate * frame_size / enc->rate + 4) / 8; } ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), GST_BUFFER_OFFSET_NONE, bytes_per_packet, GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf); if (GST_FLOW_OK != ret) goto done; GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size, bytes); #ifdef HAVE_CELT_0_8 outsize = celt_encode (enc->state, data, frame_size, GST_BUFFER_DATA (outbuf), bytes_per_packet); #else outsize = celt_encode (enc->state, data, NULL, GST_BUFFER_DATA (outbuf), bytes_per_packet); #endif if (outsize < 0) { GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("encoding failed: %d", outsize)); ret = GST_FLOW_ERROR; goto done; } GST_DEBUG_OBJECT (enc, "encoding %d bytes", bytes); ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf, frame_size); done: g_free (data0); return ret; }
int main(int argc, char *argv[]) { int err; char *inFile, *outFile; FILE *fin, *fout; CELTMode *mode=NULL; CELTEncoder *enc; CELTDecoder *dec; int len; celt_int32 frame_size, channels; int bytes_per_packet; unsigned char data[MAX_PACKET]; int rate; int complexity; #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) int i; double rmsd = 0; #endif int count = 0; celt_int32 skip; celt_int16 *in, *out; if (argc != 9 && argc != 8 && argc != 7) { fprintf (stderr, "Usage: testcelt <rate> <channels> <frame size> " " <bytes per packet> [<complexity> [packet loss rate]] " "<input> <output>\n"); return 1; } rate = atoi(argv[1]); channels = atoi(argv[2]); frame_size = atoi(argv[3]); mode = celt_mode_create(rate, frame_size, NULL); if (mode == NULL) { fprintf(stderr, "failed to create a mode\n"); return 1; } bytes_per_packet = atoi(argv[4]); if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) { fprintf (stderr, "bytes per packet must be between 0 and %d\n", MAX_PACKET); return 1; } inFile = argv[argc-2]; fin = fopen(inFile, "rb"); if (!fin) { fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); return 1; } outFile = argv[argc-1]; fout = fopen(outFile, "wb+"); if (!fout) { fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); return 1; } enc = celt_encoder_create_custom(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the encoder: %s\n", celt_strerror(err)); return 1; } dec = celt_decoder_create_custom(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the decoder: %s\n", celt_strerror(err)); return 1; } celt_decoder_ctl(dec, CELT_GET_LOOKAHEAD(&skip)); if (argc>7) { complexity=atoi(argv[5]); celt_encoder_ctl(enc,CELT_SET_COMPLEXITY(complexity)); } in = (celt_int16*)malloc(frame_size*channels*sizeof(celt_int16)); out = (celt_int16*)malloc(frame_size*channels*sizeof(celt_int16)); while (!feof(fin)) { int ret; err = fread(in, sizeof(short), frame_size*channels, fin); if (feof(fin)) break; len = celt_encode(enc, in, frame_size, data, bytes_per_packet); if (len <= 0) fprintf (stderr, "celt_encode() failed: %s\n", celt_strerror(len)); /* This is for simulating bit errors */ #if 0 int errors = 0; int eid = 0; /* This simulates random bit error */ for (i=0;i<len*8;i++) { if (rand()%atoi(argv[8])==0) { if (i<64) { errors++; eid = i; } data[i/8] ^= 1<<(7-(i%8)); } } if (errors == 1) data[eid/8] ^= 1<<(7-(eid%8)); else if (errors%2 == 1) data[rand()%8] ^= 1<<rand()%8; #endif #if 1 /* Set to zero to use the encoder's output instead */ /* This is to simulate packet loss */ if (argc==9 && rand()%1000<atoi(argv[argc-3])) /*if (errors && (errors%2==0))*/ ret = celt_decode(dec, NULL, len, out, frame_size); else ret = celt_decode(dec, data, len, out, frame_size); if (ret < 0) fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(ret)); #else for (i=0;i<ret*channels;i++) out[i] = in[i]; #endif #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) for (i=0;i<ret*channels;i++) { rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]); /*out[i] -= in[i];*/ } #endif count++; fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout); skip = 0; } PRINT_MIPS(stderr); celt_encoder_destroy(enc); celt_decoder_destroy(dec); fclose(fin); fclose(fout); celt_mode_destroy(mode); free(in); free(out); #if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) if (rmsd > 0) { rmsd = sqrt(rmsd/(1.0*frame_size*channels*count)); fprintf (stderr, "Error: encoder doesn't match decoder\n"); fprintf (stderr, "RMS mismatch is %f\n", rmsd); return 1; } else { fprintf (stderr, "Encoder matches decoder!!\n"); } #endif return 0; }
int main(int argc, char** argv) { int current, pos; celt_int16 * sample_buffer; unsigned char * encoded_buffer; double * out_buffer; int sample_rate; int sample_bits; int sample_channels; int sample_buffer_size; int sample; int sample_msec; int sample_size; float freq; double ampl, phase, frequency; int i, j, k; uint32_t frames; // FIXME! 4 byte! FILE * fd; int bad; int badbytes, lostbytes, totalbytes; struct Chord chord; // Sound output through libao struct AOutput * device; CELTMode * cm; CELTEncoder * ce; CELTDecoder * cd; int * error; int compressed; srand(time(NULL)); // Opening sound file for reading source data fd = fopen("rex.wav", "rb"); fseek(fd, 40, SEEK_SET); fread(&frames, sizeof(uint64_t), 1, fd); frames = 800000000; printf("%d\n", frames); // Hardcoded parameters for DSP sample_rate = 44100; // Desc. frequency, Hz sample_bits = 16; // Bits per sample sample_channels = 2; // Stereo // sample_msec = 10; // Size of sample, 100 ms for 10 Hz FFT freq. resolution sample_size = 1024; //sample_size = (int)(sample_rate * (sample_msec / 1000.0F)); sample_buffer_size = sample_size * sample_bits/8 * sample_channels; sample_buffer = (celt_int16 *) calloc(sample_buffer_size, sizeof(char)); encoded_buffer = (unsigned char *) calloc(sample_buffer_size, sizeof(char)); out_buffer = (double *) calloc(sample_buffer_size / (sample_bits/8), sizeof(double)); device = aout_init(); cm = celt_mode_create(sample_rate, sample_size, NULL); //printf("1\n"); ce = celt_encoder_create(cm, sample_channels, NULL); cd = celt_decoder_create(cm, sample_channels, NULL); //printf("2\n"); celt_encoder_ctl(ce, CELT_SET_COMPLEXITY(10)); celt_encoder_ctl(ce, CELT_SET_PREDICTION(2)); celt_encoder_ctl(ce, CELT_SET_VBR_RATE(160000)); // Reading util end of file (frames - number of frames in WAV) badbytes = totalbytes = lostbytes = 0; for (i = 0; i < (sample_rate / sample_size) * (frames / (sample_rate * sample_channels * (sample_bits / 8))) ; ++i) { // Reading sample from file read_sample_into_buffer(fd, (char *)sample_buffer, sample_size); printf("%d %d \n", (sample_rate / sample_size) * (frames / (sample_rate * sample_channels * (sample_bits / 8))) , i); printf("Sample_buffer_size: %d\n", sample_buffer_size); compressed = celt_encode(ce, sample_buffer, NULL, encoded_buffer, 1024); printf("Compressed bytes: %d, bitrate: %d kbps\n", compressed, (int)((sample_rate * sample_bits * sample_channels / 1024) * (compressed * 1.0F / sample_buffer_size))); memset(sample_buffer, 0, sample_buffer_size); if (rand() > (int)(0.95 * RAND_MAX)) { bad = rand() % (compressed / 4) + 5; printf("Packet error, wiped %d bytes\n", bad); memcpy(encoded_buffer + 2 * (compressed / 3) + 4, encoded_buffer, bad); badbytes += bad; } if (rand() > (int)(0.0075 * RAND_MAX)) { celt_decode(cd, encoded_buffer, compressed, sample_buffer); aout_play(device, sample_buffer, sample_buffer_size); } else { usleep(sample_size * 1000000 / sample_rate); printf("Packet was lost\n"); lostbytes += compressed; } totalbytes += compressed; printf("Total kbytes: %d, lost: %d (%.3f proc), damaged: %d (%.3f proc)\n", totalbytes / 1024, lostbytes / 1024, lostbytes * 100.0F / totalbytes , badbytes / 1024, badbytes * 100.0F / totalbytes ); } aout_close(device); return 0; }
int main(int argc, char **argv) { int sd, rc, n, tmp; char msg[MAX_MSG]; int nfds; int send_timestamp = 0; int recv_started = 0; struct pollfd *pfds; struct alsa_dev *dev; CELTEncoder *enc_state; CELTDecoder *dec_state; CELTMode *mode; struct sched_param param; JitterBuffer *jitter; SpeexEchoState *echo_state; char mac_own[6], mac_remote[6]; if (argc != 4) panic("Usage %s plughw:0,0 <lmac in xx:xx:xx:xx:xx:xx> <rmac>\n", argv[0]); register_signal(SIGINT, sighandler); hack_mac(mac_own, argv[2], strlen(argv[2])); hack_mac(mac_remote, argv[3], strlen(argv[3])); sd = socket(AF_LANA, SOCK_RAW, 0); if (sd < 0) panic("%s: cannot open socket \n", argv[0]); printf("If ready hit key!\n"); //user must do binding getchar(); dev = alsa_open(argv[1], SAMPLING_RATE, CHANNELS, FRAME_SIZE); mode = celt_mode_create(SAMPLING_RATE, FRAME_SIZE, NULL); enc_state = celt_encoder_create(mode, CHANNELS, NULL); dec_state = celt_decoder_create(mode, CHANNELS, NULL); param.sched_priority = sched_get_priority_min(SCHED_FIFO); if (sched_setscheduler(0, SCHED_FIFO, ¶m)) whine("sched_setscheduler error!\n"); /* Setup all file descriptors for poll()ing */ nfds = alsa_nfds(dev); pfds = xmalloc(sizeof(*pfds) * (nfds + 1)); alsa_getfds(dev, pfds, nfds); pfds[nfds].fd = sd; pfds[nfds].events = POLLIN; /* Setup jitter buffer using decoder */ jitter = jitter_buffer_init(FRAME_SIZE); tmp = FRAME_SIZE; jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MARGIN, &tmp); /* Echo canceller with 200 ms tail length */ echo_state = speex_echo_state_init(FRAME_SIZE, 10 * FRAME_SIZE); tmp = SAMPLING_RATE; speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp); register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); alsa_start(dev); printf("ALSA started!\n"); itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = interval; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = interval; setitimer(ITIMER_REAL, &itimer, NULL); while (!sigint) { poll(pfds, nfds + 1, -1); /* Received packets */ if (pfds[nfds].revents & POLLIN) { memset(msg, 0, MAX_MSG); n = recv(sd, msg, MAX_MSG, 0); if (n <= 0) goto do_alsa; pkts_in++; int recv_timestamp; memcpy(&recv_timestamp, msg, sizeof(recv_timestamp)); JitterBufferPacket packet; packet.data = msg+4/*+6+6+2*/; packet.len = n-4/*-6-6-2*/; packet.timestamp = recv_timestamp; packet.span = FRAME_SIZE; packet.sequence = 0; /* Put content of the packet into the jitter buffer, except for the pseudo-header */ jitter_buffer_put(jitter, &packet); recv_started = 1; } do_alsa: /* Ready to play a frame (playback) */ if (alsa_play_ready(dev, pfds, nfds)) { short pcm[FRAME_SIZE * CHANNELS] = {0}; if (recv_started) { JitterBufferPacket packet; /* Get audio from the jitter buffer */ packet.data = msg; packet.len = MAX_MSG; jitter_buffer_tick(jitter); jitter_buffer_get(jitter, &packet, FRAME_SIZE, NULL); if (packet.len == 0) packet.data=NULL; celt_decode(dec_state, (const unsigned char *) packet.data, packet.len, pcm); } /* Playback the audio and reset the echo canceller if we got an underrun */ alsa_write(dev, pcm, FRAME_SIZE); // if (alsa_write(dev, pcm, FRAME_SIZE)) // speex_echo_state_reset(echo_state); /* Put frame into playback buffer */ // speex_echo_playback(echo_state, pcm); } /* Audio available from the soundcard (capture) */ if (alsa_cap_ready(dev, pfds, nfds)) { short pcm[FRAME_SIZE * CHANNELS]; //pcm2[FRAME_SIZE * CHANNELS]; char outpacket[MAX_MSG]; alsa_read(dev, pcm, FRAME_SIZE); /* Perform echo cancellation */ // speex_echo_capture(echo_state, pcm, pcm2); // for (i = 0; i < FRAME_SIZE * CHANNELS; ++i) // pcm[i] = pcm2[i]; celt_encode(enc_state, pcm, NULL, (unsigned char *) (outpacket+4+6+6+2), PACKETSIZE); /* Pseudo header: four null bytes and a 32-bit timestamp; XXX hack */ memcpy(outpacket,mac_remote,6); memcpy(outpacket+6,mac_own,6); outpacket[6+6] = (uint8_t) 0xac; outpacket[6+6+1] = (uint8_t) 0xdc; memcpy(outpacket+6+6+2, &send_timestamp, sizeof(send_timestamp)); send_timestamp += FRAME_SIZE; rc = sendto(sd, outpacket, PACKETSIZE+4+6+6+2, 0, NULL, 0); if (rc < 0) panic("cannot send to socket"); pkts_out++; } } itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, NULL); close(sd); return 0; }
int CeltCodec::Encode(const SoundBuffer &pcmFrame, unsigned char *compressed, int bitrate) { celt_encoder_ctl(Encoder(), CELT_SET_PREDICTION(0)); return celt_encode(Encoder(), (celt_int16*)&pcmFrame.data[0], MUMBLE_AUDIO_SAMPLES_IN_FRAME, compressed, qMin(bitrate / (8 * 100), 127)); }
static GstFlowReturn gst_celt_enc_encode (GstCeltEnc * enc, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; gint frame_size = enc->frame_size; gint bytes = frame_size * 2 * enc->channels; gint bytes_per_packet; gint16 *data, *data0 = NULL; gint outsize, size; GstBuffer *outbuf; GstMapInfo map, omap; if (G_LIKELY (buf)) { gst_buffer_map (buf, &map, GST_MAP_READ); data = (gint16 *) map.data; size = map.size; if (G_UNLIKELY (map.size % bytes)) { GST_DEBUG_OBJECT (enc, "draining; adding silence samples"); size = ((size / bytes) + 1) * bytes; data0 = g_malloc0 (size); memcpy (data0, data, size); data = data0; } } else { GST_DEBUG_OBJECT (enc, "nothing to drain"); goto done; } frame_size = size / (2 * enc->channels); if (enc->cbr) { bytes_per_packet = (enc->bitrate * frame_size / enc->rate + 4) / 8; } else { bytes_per_packet = (enc->max_bitrate * frame_size / enc->rate + 4) / 8; } outbuf = gst_buffer_new_and_alloc (bytes_per_packet); GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size, bytes); gst_buffer_map (outbuf, &omap, GST_MAP_WRITE); #ifdef HAVE_CELT_0_8 outsize = celt_encode (enc->state, data, frame_size, omap.data, bytes_per_packet); #else outsize = celt_encode (enc->state, data, NULL, omap.data, bytes_per_packet); #endif gst_buffer_unmap (outbuf, &omap); gst_buffer_unmap (buf, &map); if (outsize < 0) { GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("encoding failed: %d", outsize)); ret = GST_FLOW_ERROR; goto done; } GST_DEBUG_OBJECT (enc, "encoding %d bytes", bytes); ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf, frame_size); done: g_free (data0); return ret; }