int opus_multistream_encode( OpusMSEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) { int i, ret; VARDECL(float, in); ALLOC_STACK; ALLOC(in, frame_size*st->layout.nb_channels, float); for (i=0;i<frame_size*st->layout.nb_channels;i++) in[i] = (1.f/32768.f)*pcm[i]; ret = opus_multistream_encode_float(st, in, frame_size, data, max_data_bytes); RESTORE_STACK; return ret; }
static block_t *Encode(encoder_t *enc, block_t *buf) { encoder_sys_t *sys = enc->p_sys; if (!buf) return NULL; mtime_t i_pts = buf->i_pts - (mtime_t) CLOCK_FREQ * (mtime_t) sys->i_samples_delay / (mtime_t) enc->fmt_in.audio.i_rate; sys->i_samples_delay += buf->i_nb_samples; block_t *result = NULL; unsigned src_start = 0; unsigned padding_start = 0; /* The maximum Opus frame size is 1275 bytes + TOC sequence length. */ const unsigned OPUS_MAX_ENCODED_BYTES = ((1275 + 3) * sys->nb_streams) - 2; while (sys->i_nb_samples + buf->i_nb_samples >= OPUS_FRAME_SIZE) { block_t *out_block = block_Alloc(OPUS_MAX_ENCODED_BYTES); /* add padding to beginning */ if (sys->padding) { const size_t leftover_space = OPUS_FRAME_SIZE - sys->i_nb_samples; padding_start = fill_buffer(enc, padding_start, sys->padding, __MIN(sys->padding->i_nb_samples, leftover_space)); if (sys->padding->i_nb_samples <= 0) { block_Release(sys->padding); sys->padding = NULL; } } /* padding may have been freed either before or inside previous * if-statement */ if (!sys->padding) { const size_t leftover_space = OPUS_FRAME_SIZE - sys->i_nb_samples; src_start = fill_buffer(enc, src_start, buf, __MIN(buf->i_nb_samples, leftover_space)); } opus_int32 bytes_encoded = opus_multistream_encode_float(sys->enc, sys->buffer, OPUS_FRAME_SIZE, out_block->p_buffer, out_block->i_buffer); if (bytes_encoded < 0) { block_Release(out_block); } else { out_block->i_length = (mtime_t) CLOCK_FREQ * (mtime_t) OPUS_FRAME_SIZE / (mtime_t) enc->fmt_in.audio.i_rate; out_block->i_dts = out_block->i_pts = i_pts; sys->i_samples_delay -= OPUS_FRAME_SIZE; i_pts += out_block->i_length; sys->i_nb_samples = 0; out_block->i_buffer = bytes_encoded; block_ChainAppend(&result, out_block); } } /* put leftover samples at beginning of buffer */ if (buf->i_nb_samples > 0) fill_buffer(enc, src_start, buf, buf->i_nb_samples); return result; }
int krad_opus_encoder_read (krad_opus_t *krad_opus, unsigned char *buffer, int *nframes) { int ready; int bytes; int resp; int s, c; while (krad_ringbuffer_read_space (krad_opus->ringbuf[krad_opus->channels - 1]) >= 512 * 4 ) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->ret = krad_ringbuffer_peek (krad_opus->ringbuf[c], (char *)krad_opus->samples[c], (512 * 4) ); krad_opus->src_data[c].data_in = krad_opus->samples[c]; krad_opus->src_data[c].input_frames = 512; krad_opus->src_data[c].data_out = krad_opus->resampled_samples[c]; krad_opus->src_data[c].output_frames = 2048; krad_opus->src_error[c] = src_process (krad_opus->src_resampler[c], &krad_opus->src_data[c]); if (krad_opus->src_error[c] != 0) { failfast ("Krad Opus Encoder: src resampler error: %s\n", src_strerror(krad_opus->src_error[c])); } krad_ringbuffer_read_advance (krad_opus->ringbuf[c], (krad_opus->src_data[c].input_frames_used * 4) ); krad_opus->ret = krad_ringbuffer_write (krad_opus->resampled_ringbuf[c], (char *)krad_opus->resampled_samples[c], (krad_opus->src_data[c].output_frames_gen * 4) ); } } if (krad_opus->new_bitrate != krad_opus->bitrate) { krad_opus->bitrate = krad_opus->new_bitrate; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE(krad_opus->bitrate)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: bitrate request failed %s\n", opus_strerror (resp)); } else { printk ("Krad Opus Encoder: set opus bitrate %d\n", krad_opus->bitrate); } } if (krad_opus->new_frame_size != krad_opus->frame_size) { krad_opus->frame_size = krad_opus->new_frame_size; printk ("Krad Opus Encoder: frame size is now %d\n", krad_opus->frame_size); } if (krad_opus->new_complexity != krad_opus->complexity) { krad_opus->complexity = krad_opus->new_complexity; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_COMPLEXITY(krad_opus->complexity)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: complexity request failed %s. \n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: set opus complexity %d\n", krad_opus->complexity); } } if (krad_opus->new_signal != krad_opus->signal) { krad_opus->signal = krad_opus->new_signal; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_SIGNAL(krad_opus->signal)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: signal request failed %s\n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: set opus signal mode %d\n", krad_opus->signal); } } if (krad_opus->new_bandwidth != krad_opus->bandwidth) { krad_opus->bandwidth = krad_opus->new_bandwidth; resp = opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BANDWIDTH(krad_opus->bandwidth)); if (resp != OPUS_OK) { failfast ("Krad Opus Encoder: bandwidth request failed %s\n", opus_strerror(resp)); } else { printk ("Krad Opus Encoder: Set Opus bandwidth mode %d\n", krad_opus->bandwidth); } } ready = 1; for (c = 0; c < krad_opus->channels; c++) { if (krad_ringbuffer_read_space (krad_opus->resampled_ringbuf[c]) < krad_opus->frame_size * 4) { ready = 0; } } if (ready == 1) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->ret = krad_ringbuffer_read (krad_opus->resampled_ringbuf[c], (char *)krad_opus->resampled_samples[c], (krad_opus->frame_size * 4) ); } for (s = 0; s < krad_opus->frame_size; s++) { for (c = 0; c < krad_opus->channels; c++) { krad_opus->interleaved_resampled_samples[s * krad_opus->channels + c] = krad_opus->resampled_samples[c][s]; } } bytes = opus_multistream_encode_float (krad_opus->encoder, krad_opus->interleaved_resampled_samples, krad_opus->frame_size, buffer, krad_opus->frame_size * 2); if (bytes < 0) { failfast ("Krad Opus Encoding failed: %s.", opus_strerror (bytes)); } *nframes = krad_opus->frame_size; return bytes; } return 0; }