Add an initializer for TonalityAnalysisState.
authorRalph Giles <giles@mozilla.com>
Wed, 30 Dec 2015 18:00:17 +0000 (10:00 -0800)
committerRalph Giles <giles@mozilla.com>
Thu, 31 Dec 2015 08:42:43 +0000 (00:42 -0800)
This interns the asm flags parameter in the state struct
so we don't need to pass it with every call. It can be
expensive, so we don't want to query every run_analysis()
call, but since this (private) api is used by webrtc code
we need to provide a supportable interface for filling in
the correct value.

Note the initialization code is partially duplicated between
opus_encoder_init and the OPUS_RESET_STATE switch case, so we
must re-initialize it there.

Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
src/analysis.c
src/analysis.h
src/opus_encoder.c

index 322e53c..f8187d0 100644 (file)
@@ -138,6 +138,13 @@ static OPUS_INLINE float fast_atan2f(float y, float x) {
    }
 }
 
+void tonality_analysis_init(TonalityAnalysisState *tonal)
+{
+  /* Initialize reusable fields. */
+  tonal->arch = opus_select_arch();
+  /* Other fields will be overwritten in use. */
+}
+
 void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)
 {
    int pos;
@@ -187,7 +194,7 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
    info_out->music_prob = psum;
 }
 
-static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix, int arch)
+static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
 {
     int i, b;
     const kiss_fft_state *kfft;
@@ -260,7 +267,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
     remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
     downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);
     tonal->mem_fill = 240 + remaining;
-    opus_fft(kfft, in, out, arch);
+    opus_fft(kfft, in, out, tonal->arch);
 #ifndef FIXED_POINT
     /* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */
     if (celt_isnan(out[0].r))
@@ -633,7 +640,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
 
 void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
                  int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
-                 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info, int arch)
+                 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info)
 {
    int offset;
    int pcm_len;
@@ -646,7 +653,7 @@ void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, co
       pcm_len = analysis_frame_size - analysis->analysis_offset;
       offset = analysis->analysis_offset;
       do {
-         tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix, arch);
+         tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
          offset += 480;
          pcm_len -= 480;
       } while (pcm_len>0);
index 9c328e8..9c2b978 100644 (file)
@@ -76,12 +76,21 @@ typedef struct {
    int read_pos;
    int read_subframe;
    AnalysisInfo info[DETECT_SIZE];
+   int arch;
 } TonalityAnalysisState;
 
+/** Initialize a TonalityAnalysisState struct.
+ *
+ * This performs some possibly slow initialization steps which should
+ * not be repeated every analysis step. No allocated memory is retained
+ * by the state struct, so no cleanup call is required.
+ */
+void tonality_analysis_init(TonalityAnalysisState *analysis);
+
 void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len);
 
 void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
                  int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
-                 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info, int arch);
+                 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info);
 
 #endif
index 7403a4c..e1ca868 100644 (file)
@@ -242,6 +242,10 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
     st->mode = MODE_HYBRID;
     st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
 
+#ifndef DISABLE_FLOAT_API
+    tonality_analysis_init(&st->analysis);
+#endif
+
     return OPUS_OK;
 }
 
@@ -1005,7 +1009,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
        analysis_read_subframe_bak = st->analysis.read_subframe;
        run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
              c1, c2, analysis_channels, st->Fs,
-             lsb_depth, downmix, &analysis_info, st->arch);
+             lsb_depth, downmix, &analysis_info);
     }
 #else
     (void)analysis_pcm;
@@ -2463,6 +2467,9 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
            st->mode = MODE_HYBRID;
            st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
            st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
+#ifndef DISABLE_FLOAT_API
+           tonality_analysis_init(&st->analysis);
+#endif
         }
         break;
         case OPUS_SET_FORCE_MODE_REQUEST: