diff --git a/encoder/ixheaace_api.c b/encoder/ixheaace_api.c index ea870d4..e1481b3 100644 --- a/encoder/ixheaace_api.c +++ b/encoder/ixheaace_api.c @@ -2473,6 +2473,11 @@ static IA_ERRORCODE ia_enhaacplus_enc_init(ixheaace_api_struct *pstr_api_struct, ? core_ch : pstr_api_struct->config[ele_idx].i_channels_mode); + WORD32 is_single_rate = ( + pstr_api_struct->pstr_state->aot == AOT_AAC_ELD && + (!pstr_api_struct->pstr_state->mps_enable + || (pstr_api_struct->pstr_state->mps_tree_config == TREE_212 && pstr_aac_config->sample_rate < 27713))); + if (!(pstr_api_struct->config[ele_idx].aac_classic) && ixheaace_is_sbr_setting_available( pstr_aac_config->bit_rate, @@ -2481,7 +2486,7 @@ static IA_ERRORCODE ia_enhaacplus_enc_init(ixheaace_api_struct *pstr_api_struct, : pstr_api_struct->config[ele_idx].chmode_nchannels), pstr_aac_config->sample_rate, &core_sample_rate, pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab, - pstr_api_struct->pstr_state->aot)) { + pstr_api_struct->pstr_state->aot, is_single_rate)) { ixheaace_str_sbr_cfg spectral_band_replication_config; ixheaace_initialize_sbr_defaults(&spectral_band_replication_config); @@ -2490,6 +2495,7 @@ static IA_ERRORCODE ia_enhaacplus_enc_init(ixheaace_api_struct *pstr_api_struct, spectral_band_replication_config.crc_sbr = 0; spectral_band_replication_config.parametric_coding = 1; spectral_band_replication_config.is_esbr = pstr_api_struct->config[0].esbr_flag; + spectral_band_replication_config.sample_rate_mode = is_single_rate ? IXHEAACE_SINGLE_RATE : IXHEAACE_DUAL_RATE; if (pstr_api_struct->pstr_state->aot == AOT_AAC_ELD) { spectral_band_replication_config.is_ld_sbr = 1; spectral_band_replication_config.sbr_codec = ELD_SBR; diff --git a/encoder/ixheaace_sbr_freq_scaling.c b/encoder/ixheaace_sbr_freq_scaling.c index e3e7921..8dc9529 100644 --- a/encoder/ixheaace_sbr_freq_scaling.c +++ b/encoder/ixheaace_sbr_freq_scaling.c @@ -19,6 +19,8 @@ */ #include +#include +#include "iusace_type_def.h" #include "ixheaac_type_def.h" #include "ixheaac_constants.h" #include "ixheaace_error_codes.h" @@ -371,6 +373,22 @@ ixheaace_get_sbr_start_freq_raw(WORD32 start_freq, WORD32 qmf_bands, WORD32 fs) return result; } +WORD32 +ixheaace_get_sbr_stop_freq_raw(WORD32 stop_freq, WORD32 qmf_bands, WORD32 fs) { + WORD32 result; + + if (stop_freq < 0 || stop_freq > 13) { + return -1; + } + + result = ixheaace_get_stop_freq(fs, stop_freq); + + result = (result * fs / qmf_bands + 1) >> 1; + + return result; +} + + static WORD32 ixheaace_number_of_bands(WORD32 b_p_o, WORD32 start, WORD32 stop, FLOAT32 warp_fac) { WORD32 result = 0; @@ -416,6 +434,24 @@ static VOID ixheaace_cum_sum(WORD32 start_value, WORD32 *ptr_diff, WORD32 length } } +WORD32 +ixheaace_find_stop_band_downsample(const WORD32 sampling_freq, const WORD32 num_channels, + const WORD32 start_freq, const WORD32 stop_freq, + const ixheaace_sr_mode sample_rate_mode, WORD32 sbr_ratio_idx, + ixheaace_sbr_codec_type sbr_codec) { + WORD32 stop_freq_max = sampling_freq / 2; + WORD32 k0, k2; + IA_ERRORCODE ret; + + while (stop_freq > 0 && (ixheaace_get_sbr_stop_freq_raw(stop_freq, num_channels, sampling_freq) > stop_freq_max)) stop_freq_max--; + if ((ixheaace_get_sbr_stop_freq_raw(stop_freq, num_channels, sampling_freq) > stop_freq_max)) return -1; + + ret = ixheaace_find_start_and_stop_band(sampling_freq, num_channels, start_freq, stop_freq, sample_rate_mode, &k0, &k2, sbr_ratio_idx, sbr_codec); + if (ret != IA_NO_ERROR) return -1; + + return k2; +} + IA_ERRORCODE ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_channels, const WORD32 start_freq, const WORD32 stop_freq, @@ -440,6 +476,8 @@ ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_c return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_SAMPLERATE_MODE; } + printf("start freq: %d, stop freq: %d\n", start_freq, stop_freq); + if (stop_freq < 14) { switch (sbr_codec) { case USAC_SBR: { @@ -495,14 +533,17 @@ ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_c } else { if (sampling_freq <= 32000) { if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_LE32KHZ) { + printf("error: bad coefs (32000): %d\n", *ptr_k2 - *ptr_k0); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; } } else if (sampling_freq == 44100) { if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_EQ44KHZ) { + printf("error: bad coefs (44100): %d\n", *ptr_k2 - *ptr_k0); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; } } else if (sampling_freq >= 48000) { if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_GE48KHZ) { + printf("error: bad coefs (48000): %d\n", *ptr_k2 - *ptr_k0); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; } } else { @@ -511,6 +552,7 @@ ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_c } if ((*ptr_k2 - *ptr_k0) < 0) { + printf("error: negative coefs: %d\n", *ptr_k2 - *ptr_k0); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; } @@ -572,6 +614,7 @@ ixheaace_update_freq_scale(UWORD8 *ptr_k_master, WORD32 *ptr_num_bands, const WO ixheaace_shellsort_int(diff0, num_bands0); if (diff0[0] == 0) { + printf("bad number bands at diff0\n"); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_NUM_BANDS; } @@ -594,6 +637,7 @@ ixheaace_update_freq_scale(UWORD8 *ptr_k_master, WORD32 *ptr_num_bands, const WO ixheaace_shellsort_int(diff0, num_bands0); if (diff0[0] == 0) { + printf("bad number bands at diff0\n"); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_NUM_BANDS; } @@ -643,6 +687,7 @@ ixheaace_update_freq_scale(UWORD8 *ptr_k_master, WORD32 *ptr_num_bands, const WO } if (*ptr_num_bands < 1) { + printf("bad number bands at ptr_num_bands\n"); return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_NUM_BANDS; } diff --git a/encoder/ixheaace_sbr_freq_scaling.h b/encoder/ixheaace_sbr_freq_scaling.h index fe107e1..0c31aba 100644 --- a/encoder/ixheaace_sbr_freq_scaling.h +++ b/encoder/ixheaace_sbr_freq_scaling.h @@ -43,3 +43,8 @@ ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_c ixheaace_sbr_codec_type sbr_codec); WORD32 ixheaace_get_sbr_start_freq_raw(WORD32 start_freq, WORD32 qmf_bands, WORD32 fs); +WORD32 ixheaace_get_sbr_stop_freq_raw(WORD32 stop_freq, WORD32 qmf_bands, WORD32 fs); +WORD32 ixheaace_find_stop_band_downsample(const WORD32 sampling_freq, const WORD32 num_channels, + const WORD32 start_freq, const WORD32 stop_freq, + const ixheaace_sr_mode sample_rate_mode, WORD32 sbr_ratio_idx, + ixheaace_sbr_codec_type sbr_codec); \ No newline at end of file diff --git a/encoder/ixheaace_sbr_main.c b/encoder/ixheaace_sbr_main.c index b8594e8..a0dcc42 100644 --- a/encoder/ixheaace_sbr_main.c +++ b/encoder/ixheaace_sbr_main.c @@ -18,6 +18,7 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ +#include #include #include "ixheaac_type_def.h" @@ -380,7 +381,7 @@ static IA_ERRORCODE ixheaace_create_env_channel( UWORD32 ixheaace_is_sbr_setting_available(UWORD32 bitrate, UWORD32 num_output_channels, UWORD32 sample_rate_input, UWORD32 *ptr_core_sr, - ixheaace_str_qmf_tabs *pstr_qmf_tab, WORD32 aot) { + ixheaace_str_qmf_tabs *pstr_qmf_tab, WORD32 aot, WORD32 single_rate) { FLAG table_found = IXHEAACE_TABLE_IDX_NOT_FOUND; WORD32 idx_sr; WORD32 idx_ch; @@ -399,7 +400,7 @@ ixheaace_is_sbr_setting_available(UWORD32 bitrate, UWORD32 num_output_channels, } #endif - *ptr_core_sr = sample_rate_input / 2; + *ptr_core_sr = single_rate ? sample_rate_input : (sample_rate_input / 2); table_found = ia_enhaacplus_enc_get_sbr_tuning_table_idx( bitrate, num_output_channels, *ptr_core_sr, pstr_qmf_tab, NULL, &idx_sr, &idx_ch, @@ -407,6 +408,8 @@ ixheaace_is_sbr_setting_available(UWORD32 bitrate, UWORD32 num_output_channels, ((AOT_AAC_ELD == aot) ? pstr_qmf_tab->sbr_tuning_table_ld : pstr_qmf_tab->sbr_tuning_table_lc)); + printf("core_sr: %d, sr_input: %d\n", *ptr_core_sr, sample_rate_input); + return (table_found == IXHEAACE_TABLE_IDX_NOT_FOUND) ? 0 : 1; } @@ -490,6 +493,10 @@ VOID ixheaace_adjust_sbr_settings(const ixheaace_pstr_sbr_cfg pstr_config, UWORD pstr_qmf_tab->sbr_tuning_table_ld[idx_sr][idx_ch][idx_entry].stereo_mode; pstr_config->freq_scale = pstr_qmf_tab->sbr_tuning_table_ld[idx_sr][idx_ch][idx_entry].freq_scale; + + if (pstr_config->sample_rate_mode == IXHEAACE_SINGLE_RATE) { + WORD32 stopFreq; + } break; } default: { @@ -597,6 +604,7 @@ VOID ixheaace_initialize_sbr_defaults(ixheaace_pstr_sbr_cfg pstr_config) { pstr_config->sbr_harmonic = 0; pstr_config->sbr_ratio_idx = 0; // NO_SBR pstr_config->use_low_freq_res = 0; + pstr_config->sample_rate_mode = IXHEAACE_DUAL_RATE; } static IA_ERRORCODE ia_enhaacplus_enc_update_freq_band_tab( @@ -967,7 +975,7 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg pstr_env_enc->str_sbr_cfg.stereo_mode = (params->codec_settings.num_channels == 2) ? params->stereo_mode : IXHEAACE_SBR_MODE_MONO; - if (params->codec_settings.sample_freq <= 24000 || !params->is_ld_sbr) { + if (params->sample_rate_mode == IXHEAACE_DUAL_RATE) { pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_DUAL_RATE; if (params->sbr_codec == USAC_SBR) { pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; @@ -982,6 +990,7 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_SINGLE_RATE; pstr_env_enc->str_sbr_cfg.sample_freq = params->codec_settings.sample_freq; } + printf("sample rate mode: %d, sample freq: %d\n", pstr_env_enc->str_sbr_hdr.sample_rate_mode, pstr_env_enc->str_sbr_cfg.sample_freq); if (params->is_ld_sbr) { pstr_env_enc->str_sbr_bs.count_send_header_data = -1; } else { @@ -1043,7 +1052,7 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg pstr_env_enc->str_sbr_cfg.use_parametric_coding = params->parametric_coding; err_code = ia_enhaacplus_enc_update_freq_band_tab( - &pstr_env_enc->str_sbr_cfg, &pstr_env_enc->str_sbr_hdr, IXHEAACE_QMF_CHANNELS); + &pstr_env_enc->str_sbr_cfg, &pstr_env_enc->str_sbr_hdr, IXHEAACE_QMF_CHANNELS / (pstr_env_enc->str_sbr_hdr.sample_rate_mode == IXHEAACE_SINGLE_RATE ? 2 : 1)); if (err_code) { return err_code; } diff --git a/encoder/ixheaace_sbr_main.h b/encoder/ixheaace_sbr_main.h index f84dccd..d8fdc2d 100644 --- a/encoder/ixheaace_sbr_main.h +++ b/encoder/ixheaace_sbr_main.h @@ -85,6 +85,7 @@ typedef struct ixheaace_str_sbr_cfg { WORD32 hq_esbr; ixheaace_sbr_codec_type sbr_codec; WORD32 use_low_freq_res; + ixheaace_sr_mode sample_rate_mode; } ixheaace_str_sbr_cfg, *ixheaace_pstr_sbr_cfg; typedef struct ixheaace_str_sbr_enc *ixheaace_pstr_sbr_enc; @@ -92,7 +93,7 @@ typedef struct ixheaace_str_sbr_enc *ixheaace_pstr_sbr_enc; UWORD32 ixheaace_is_sbr_setting_available(UWORD32 bitrate, UWORD32 num_output_channels, UWORD32 sample_rate_input, UWORD32 *sample_rate_core, - ixheaace_str_qmf_tabs *ptr_qmf_tab, WORD32 aot); + ixheaace_str_qmf_tabs *ptr_qmf_tab, WORD32 aot, WORD32 single_rate); UWORD32 ixheaace_sbr_limit_bitrate(UWORD32 bit_rate, UWORD32 num_channels, UWORD32 core_sample_rate, ixheaace_str_qmf_tabs *ptr_qmf_tab, diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c index 8856138..576b3bc 100644 --- a/encoder/ixheaace_sbr_rom.c +++ b/encoder/ixheaace_sbr_rom.c @@ -48,7 +48,7 @@ const WORD32 vector_offset_def[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 2 const WORD32 vector_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64}; const WORD32 vector_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37, 40, 43, 47, 51, 55, 59, 64}; const WORD32 vector_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35, 38, 42, 45, 49, 54, 59, 64}; -const WORD32 vector_stop_freq_64[14] = {20, 22, 24, 26, 28, 31, 34, 37, 41, 45, 49, 54, 59, 64}; +const WORD32 vector_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34, 37, 41, 45, 49, 54, 59, 64}; const WORD32 vector_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29, 33, 37, 41, 46, 51, 57, 64}; const WORD32 vector_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27, 31, 35, 39, 44, 50, 57, 64};