OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) { if (channels < 0 || channels > 2) return OPUS_BAD_ARG; if (st==NULL) return OPUS_ALLOC_FAIL; OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); st->mode = mode; st->overlap = mode->overlap; st->stream_channels = st->channels = channels; st->downsample = 1; st->start = 0; st->end = st->mode->effEBands; st->signalling = 1; st->arch = opus_select_arch(); st->loss_count = 0; opus_custom_decoder_ctl(st, OPUS_RESET_STATE); return OPUS_OK; }
void tonality_analysis_reset(TonalityAnalysisState *tonal) { /* Clear non-reusable fields. */ char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START; OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal)); tonal->music_confidence = .9f; tonal->speech_confidence = .1f; }
int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) { void *silk_dec; CELTDecoder *celt_dec; int ret, silkDecSizeBytes; if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) || (channels!=1&&channels!=2)) return OPUS_BAD_ARG; OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); /* Initialize SILK encoder */ ret = silk_Get_Decoder_Size(&silkDecSizeBytes); if (ret) return OPUS_INTERNAL_ERROR; silkDecSizeBytes = align(silkDecSizeBytes); st->silk_dec_offset = align(sizeof(OpusDecoder)); st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes; silk_dec = (char*)st+st->silk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); st->stream_channels = st->channels = channels; st->Fs = Fs; st->DecControl.API_sampleRate = st->Fs; st->DecControl.nChannelsAPI = st->channels; st->arch = opus_select_arch(); /* Reset decoder */ ret = silk_InitDecoder( silk_dec ); if(ret)return OPUS_INTERNAL_ERROR; /* Initialize CELT decoder */ ret = celt_decoder_init(celt_dec, Fs, channels); if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); st->prev_mode = 0; st->frame_size = Fs/400; return OPUS_OK; }
static void opus_projection_copy_channel_out_short( void *dst, int dst_stride, int dst_channel, const opus_val16 *src, int src_stride, int frame_size, void *user_data) { opus_int16 *short_dst; const MappingMatrix *matrix; short_dst = (opus_int16 *)dst; matrix = (const MappingMatrix *)user_data; if (dst_channel == 0) OPUS_CLEAR(short_dst, frame_size * dst_stride); if (src != NULL) mapping_matrix_multiply_channel_out_short(matrix, src, dst_channel, src_stride, short_dst, dst_stride, frame_size); }
int opus_decoder_ctl(OpusDecoder *st, int request, ...) { int ret = OPUS_OK; va_list ap; void *silk_dec; CELTDecoder *celt_dec; silk_dec = (char*)st+st->silk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); va_start(ap, request); switch (request) { case OPUS_GET_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->bandwidth; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); if (!value) { goto bad_arg; } *value = st->rangeFinal; } break; case OPUS_RESET_STATE: { OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START, sizeof(OpusDecoder)- ((char*)&st->OPUS_DECODER_RESET_START - (char*)st)); celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); silk_InitDecoder( silk_dec ); st->stream_channels = st->channels; st->frame_size = st->Fs/400; } break; case OPUS_GET_SAMPLE_RATE_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->Fs; } break; case OPUS_GET_PITCH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } if (st->prev_mode == MODE_CELT_ONLY) celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); else *value = st->DecControl.prevPitchLag; } break; case OPUS_GET_GAIN_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); if (!value) { goto bad_arg; } *value = st->decode_gain; } break; case OPUS_SET_GAIN_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); if (value<-32768 || value>32767) { goto bad_arg; } st->decode_gain = value; } break; case OPUS_GET_LAST_PACKET_DURATION_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); if (!value) { goto bad_arg; } *value = st->last_packet_duration; } break; default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; break; } va_end(ap); return ret; bad_arg: va_end(ap); return OPUS_BAD_ARG; }
int opus_decoder_ctl(OpusDecoder *st, int request, ...) { int ret = OPUS_OK; va_list ap; void *silk_dec; CELTDecoder *celt_dec; silk_dec = (char*)st+st->silk_dec_offset; celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); va_start(ap, request); switch (request) { case OPUS_GET_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); *value = st->bandwidth; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); *value = st->rangeFinal; } break; case OPUS_RESET_STATE: { OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START, sizeof(OpusDecoder)- ((char*)&st->OPUS_DECODER_RESET_START - (char*)st)); celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); silk_InitDecoder( silk_dec ); st->stream_channels = st->channels; st->frame_size = st->Fs/400; } break; case OPUS_GET_PITCH_REQUEST: { int *value = va_arg(ap, opus_int32*); if (value==NULL) { ret = OPUS_BAD_ARG; break; } if (st->prev_mode == MODE_CELT_ONLY) celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); else *value = st->DecControl.prevPitchLag; } break; default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; break; } va_end(ap); return ret; }
static int opus_multistream_encoder_init_impl( OpusMSEncoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application, MappingType mapping_type ) { int coupled_size; int mono_size; int i, ret; char *ptr; if ((channels>255) || (channels<1) || (coupled_streams>streams) || (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) return OPUS_BAD_ARG; st->arch = opus_select_arch(); st->layout.nb_channels = channels; st->layout.nb_streams = streams; st->layout.nb_coupled_streams = coupled_streams; if (mapping_type != MAPPING_TYPE_SURROUND) st->lfe_stream = -1; st->bitrate_bps = OPUS_AUTO; st->application = application; st->variable_duration = OPUS_FRAMESIZE_ARG; for (i=0;i<st->layout.nb_channels;i++) st->layout.mapping[i] = mapping[i]; if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout)) return OPUS_BAD_ARG; ptr = (char*)st + align(sizeof(OpusMSEncoder)); coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); for (i=0;i<st->layout.nb_coupled_streams;i++) { ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); if(ret!=OPUS_OK)return ret; if (i==st->lfe_stream) opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); ptr += align(coupled_size); } for (;i<st->layout.nb_streams;i++) { ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); if (i==st->lfe_stream) opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); if(ret!=OPUS_OK)return ret; ptr += align(mono_size); } if (mapping_type == MAPPING_TYPE_SURROUND) { OPUS_CLEAR(ms_get_preemph_mem(st), channels); OPUS_CLEAR(ms_get_window_mem(st), channels*120); } st->mapping_type = mapping_type; return OPUS_OK; }
void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch ) { int c; int i; int LM; int pos[8] = {0}; int upsample; int frame_size; int freq_size; opus_val16 channel_offset; opus_val32 bandE[21]; opus_val16 maskLogE[3][21]; VARDECL(opus_val32, in); VARDECL(opus_val16, x); VARDECL(opus_val32, freq); SAVE_STACK; upsample = resampling_factor(rate); frame_size = len*upsample; freq_size = IMIN(960, frame_size); /* LM = log2(frame_size / 120) */ for (LM=0;LM<celt_mode->maxLM;LM++) if (celt_mode->shortMdctSize<<LM==frame_size) break; ALLOC(in, frame_size+overlap, opus_val32); ALLOC(x, len, opus_val16); ALLOC(freq, freq_size, opus_val32); channel_pos(channels, pos); for (c=0;c<3;c++) for (i=0;i<21;i++) maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT); for (c=0;c<channels;c++) { int frame; int nb_frames = frame_size/freq_size; celt_assert(nb_frames*freq_size == frame_size); OPUS_COPY(in, mem+c*overlap, overlap); (*copy_channel_in)(x, 1, pcm, channels, c, len); celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0); #ifndef FIXED_POINT { opus_val32 sum; sum = celt_inner_prod(in, in, frame_size+overlap, 0); /* This should filter out both NaNs and ridiculous signals that could cause NaNs further down. */ if (!(sum < 1e9f) || celt_isnan(sum)) { OPUS_CLEAR(in, frame_size+overlap); preemph_mem[c] = 0; } } #endif OPUS_CLEAR(bandE, 21); for (frame=0;frame<nb_frames;frame++) { opus_val32 tmpE[21]; clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1, arch); if (upsample != 1) { int bound = freq_size/upsample; for (i=0;i<bound;i++) freq[i] *= upsample; for (;i<freq_size;i++) freq[i] = 0; } compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM); /* If we have multiple frames, take the max energy. */ for (i=0;i<21;i++) bandE[i] = MAX32(bandE[i], tmpE[i]); } amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ for (i=1;i<21;i++) bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT)); for (i=19;i>=0;i--) bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT)); if (pos[c]==1) { for (i=0;i<21;i++) maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); } else if (pos[c]==3) { for (i=0;i<21;i++) maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); } else if (pos[c]==2) { for (i=0;i<21;i++) { maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); } } #if 0 for (i=0;i<21;i++) printf("%f ", bandLogE[21*c+i]); float sum=0; for (i=0;i<21;i++) sum += bandLogE[21*c+i]; printf("%f ", sum/21); #endif OPUS_COPY(mem+c*overlap, in+frame_size, overlap); } for (i=0;i<21;i++) maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); for (c=0;c<3;c++) for (i=0;i<21;i++) maskLogE[c][i] += channel_offset; #if 0 for (c=0;c<3;c++) { for (i=0;i<21;i++) printf("%f ", maskLogE[c][i]); } #endif for (c=0;c<channels;c++) { opus_val16 *mask; if (pos[c]!=0) { mask = &maskLogE[pos[c]-1][0]; for (i=0;i<21;i++) bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i]; } else { for (i=0;i<21;i++) bandLogE[21*c+i] = 0; } #if 0 for (i=0;i<21;i++) printf("%f ", bandLogE[21*c+i]); printf("\n"); #endif #if 0 float sum=0; for (i=0;i<21;i++) sum += bandLogE[21*c+i]; printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT)); printf("\n"); #endif } RESTORE_STACK; }