swr: move dither related fields to their own context
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 9 Jan 2013 17:41:12 +0000 (18:41 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 9 Jan 2013 17:41:12 +0000 (18:41 +0100)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libswresample/dither.c
libswresample/dither_template.c
libswresample/swresample.c
libswresample/swresample_internal.h

index f43d891..c79d372 100644 (file)
@@ -41,35 +41,35 @@ void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSa
     if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24;
     if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8;
 
     if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24;
     if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8;
 
-    scale *= s->dither_scale;
+    scale *= s->dither.scale;
 
 
-    s->ns_pos = 0;
-    s->ns_scale   =   scale;
-    s->ns_scale_1 = 1/scale;
-    memset(s->ns_errors, 0, sizeof(s->ns_errors));
+    s->dither.ns_pos = 0;
+    s->dither.ns_scale   =   scale;
+    s->dither.ns_scale_1 = 1/scale;
+    memset(s->dither.ns_errors, 0, sizeof(s->dither.ns_errors));
     for (i=0; filters[i].coefs; i++) {
         const filter_t *f = &filters[i];
     for (i=0; filters[i].coefs; i++) {
         const filter_t *f = &filters[i];
-        if (fabs(s->out_sample_rate - f->rate) / f->rate <= .05 && f->name == s->dither_method) {
+        if (fabs(s->out_sample_rate - f->rate) / f->rate <= .05 && f->name == s->dither.method) {
             int j;
             int j;
-            s->ns_taps = f->len;
+            s->dither.ns_taps = f->len;
             for (j=0; j<f->len; j++)
             for (j=0; j<f->len; j++)
-                s->ns_coeffs[j] = f->coefs[j];
+                s->dither.ns_coeffs[j] = f->coefs[j];
             break;
         }
     }
             break;
         }
     }
-    if (!filters[i].coefs && s->dither_method > SWR_DITHER_NS) {
+    if (!filters[i].coefs && s->dither.method > SWR_DITHER_NS) {
         av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n");
         av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n");
-        s->dither_method = SWR_DITHER_TRIANGULAR_HIGHPASS;
+        s->dither.method = SWR_DITHER_TRIANGULAR_HIGHPASS;
     }
 
     for(i=0; i<len + TMP_EXTRA; i++){
         double v;
         seed = seed* 1664525 + 1013904223;
 
     }
 
     for(i=0; i<len + TMP_EXTRA; i++){
         double v;
         seed = seed* 1664525 + 1013904223;
 
-        switch(s->dither_method){
+        switch(s->dither.method){
             case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
             default:
             case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
             default:
-                av_assert0(s->dither_method < SWR_DITHER_NB);
+                av_assert0(s->dither.method < SWR_DITHER_NB);
                 v = ((double)seed) / UINT_MAX;
                 seed = seed*1664525 + 1013904223;
                 v-= ((double)seed) / UINT_MAX;
                 v = ((double)seed) / UINT_MAX;
                 seed = seed*1664525 + 1013904223;
                 v-= ((double)seed) / UINT_MAX;
@@ -81,9 +81,9 @@ void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSa
     for(i=0; i<len; i++){
         double v;
 
     for(i=0; i<len; i++){
         double v;
 
-        switch(s->dither_method){
+        switch(s->dither.method){
             default:
             default:
-                av_assert0(s->dither_method < SWR_DITHER_NB);
+                av_assert0(s->dither.method < SWR_DITHER_NB);
                 v = tmp[i];
                 break;
             case SWR_DITHER_TRIANGULAR_HIGHPASS :
                 v = tmp[i];
                 break;
             case SWR_DITHER_TRIANGULAR_HIGHPASS :
index 7e99c50..ffa5bdd 100644 (file)
@@ -25,27 +25,27 @@ ERROR
 
 void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *srcs, AudioData *noises, int count){
     int i, j, pos, ch;
 
 void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *srcs, AudioData *noises, int count){
     int i, j, pos, ch;
-    int taps  = s->ns_taps;
-    float S   = s->ns_scale;
-    float S_1 = s->ns_scale_1;
+    int taps  = s->dither.ns_taps;
+    float S   = s->dither.ns_scale;
+    float S_1 = s->dither.ns_scale_1;
 
     for (ch=0; ch<srcs->ch_count; ch++) {
 
     for (ch=0; ch<srcs->ch_count; ch++) {
-        const float *noise = ((const float *)noises->ch[ch]) + s->dither_pos;
+        const float *noise = ((const float *)noises->ch[ch]) + s->dither.dither_pos;
         DELEM *data = (DELEM*)srcs->ch[ch];
         DELEM *data = (DELEM*)srcs->ch[ch];
-        pos  = s->ns_pos;
+        pos  = s->dither.ns_pos;
         for (i=0; i<count; i++) {
             double d1, d = data[i];
             for(j=0; j<taps; j++)
         for (i=0; i<count; i++) {
             double d1, d = data[i];
             for(j=0; j<taps; j++)
-                d -= s->ns_coeffs[j] * s->ns_errors[ch][pos + j];
+                d -= s->dither.ns_coeffs[j] * s->dither.ns_errors[ch][pos + j];
             pos = pos ? pos - 1 : pos - 1 + taps;
             d1 = rint((d + noise[i]) * S_1)*S;
             pos = pos ? pos - 1 : pos - 1 + taps;
             d1 = rint((d + noise[i]) * S_1)*S;
-            s->ns_errors[ch][pos + taps] = s->ns_errors[ch][pos] = d1 - d;
+            s->dither.ns_errors[ch][pos + taps] = s->dither.ns_errors[ch][pos] = d1 - d;
             CLIP(d1);
             data[i] = d1;
         }
     }
 
             CLIP(d1);
             data[i] = d1;
         }
     }
 
-    s->ns_pos = pos;
+    s->dither.ns_pos = pos;
 }
 
 #undef RENAME
 }
 
 #undef RENAME
index f11bbd7..218d346 100644 (file)
@@ -73,9 +73,9 @@ static const AVOption options[]={
 {"swr_flags"            , "set flags"                   , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
 {"res"                  , "force resampling"            , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_FLAG_RESAMPLE     }, INT_MIN, INT_MAX   , PARAM, "flags"},
 
 {"swr_flags"            , "set flags"                   , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
 {"res"                  , "force resampling"            , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_FLAG_RESAMPLE     }, INT_MIN, INT_MAX   , PARAM, "flags"},
 
-{"dither_scale"         , "set dither scale"            , OFFSET(dither_scale   ), AV_OPT_TYPE_FLOAT, {.dbl=1                     }, 0      , INT_MAX   , PARAM},
+{"dither_scale"         , "set dither scale"            , OFFSET(dither.scale   ), AV_OPT_TYPE_FLOAT, {.dbl=1                     }, 0      , INT_MAX   , PARAM},
 
 
-{"dither_method"        , "set dither method"           , OFFSET(dither_method  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_DITHER_NB-1, PARAM, "dither_method"},
+{"dither_method"        , "set dither method"           , OFFSET(dither.method  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_DITHER_NB-1, PARAM, "dither_method"},
 {"rectangular"          , "select rectangular dither"   , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX   , PARAM, "dither_method"},
 {"triangular"           , "select triangular dither"    , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX   , PARAM, "dither_method"},
 {"triangular_hp"        , "select triangular dither with high pass" , 0          , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
 {"rectangular"          , "select rectangular dither"   , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX   , PARAM, "dither_method"},
 {"triangular"           , "select triangular dither"    , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX   , PARAM, "dither_method"},
 {"triangular_hp"        , "select triangular dither with high pass" , 0          , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
@@ -217,7 +217,7 @@ av_cold void swr_free(SwrContext **ss){
         free_temp(&s->midbuf);
         free_temp(&s->preout);
         free_temp(&s->in_buffer);
         free_temp(&s->midbuf);
         free_temp(&s->preout);
         free_temp(&s->in_buffer);
-        free_temp(&s->dither);
+        free_temp(&s->dither.noise);
         swri_audio_convert_free(&s-> in_convert);
         swri_audio_convert_free(&s->out_convert);
         swri_audio_convert_free(&s->full_convert);
         swri_audio_convert_free(&s-> in_convert);
         swri_audio_convert_free(&s->out_convert);
         swri_audio_convert_free(&s->full_convert);
@@ -237,7 +237,7 @@ av_cold int swr_init(struct SwrContext *s){
     free_temp(&s->midbuf);
     free_temp(&s->preout);
     free_temp(&s->in_buffer);
     free_temp(&s->midbuf);
     free_temp(&s->preout);
     free_temp(&s->in_buffer);
-    free_temp(&s->dither);
+    free_temp(&s->dither.noise);
     memset(s->in.ch, 0, sizeof(s->in.ch));
     memset(s->out.ch, 0, sizeof(s->out.ch));
     swri_audio_convert_free(&s-> in_convert);
     memset(s->in.ch, 0, sizeof(s->in.ch));
     memset(s->out.ch, 0, sizeof(s->out.ch));
     swri_audio_convert_free(&s-> in_convert);
@@ -355,7 +355,7 @@ av_assert0(s->out.ch_count);
 
     s->in_buffer= s->in;
 
 
     s->in_buffer= s->in;
 
-    if(!s->resample && !s->rematrix && !s->channel_map && !s->dither_method){
+    if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
         s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
                                                    s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
         return 0;
         s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
                                                    s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
         return 0;
@@ -391,9 +391,9 @@ av_assert0(s->out.ch_count);
         set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
     }
 
         set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
     }
 
-    s->dither = s->preout;
+    s->dither.noise = s->preout;
 
 
-    if(s->rematrix || s->dither_method)
+    if(s->rematrix || s->dither.method)
         return swri_rematrix_init(s);
 
     return 0;
         return swri_rematrix_init(s);
 
     return 0;
@@ -609,7 +609,7 @@ static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_co
     if(s->resample_first ? !s->rematrix : !s->resample)
         preout= midbuf;
 
     if(s->resample_first ? !s->rematrix : !s->resample)
         preout= midbuf;
 
-    if (preout == in && s->dither_method) {
+    if (preout == in && s->dither.method) {
         av_assert1(postin == midbuf && midbuf == preout);
         postin = midbuf = preout = &preout_tmp;
     }
         av_assert1(postin == midbuf && midbuf == preout);
         postin = midbuf = preout = &preout_tmp;
     }
@@ -643,45 +643,45 @@ static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_co
     }
 
     if(preout != out && out_count){
     }
 
     if(preout != out && out_count){
-        if(s->dither_method){
+        if(s->dither.method){
             int ch, len1;
             int dither_count= FFMAX(out_count, 1<<16);
             av_assert0(preout != in);
 
             int ch, len1;
             int dither_count= FFMAX(out_count, 1<<16);
             av_assert0(preout != in);
 
-            if((ret=swri_realloc_audio(&s->dither, dither_count))<0)
+            if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)
                 return ret;
             if(ret)
                 return ret;
             if(ret)
-                for(ch=0; ch<s->dither.ch_count; ch++)
-                    swri_get_dither(s, s->dither.ch[ch], s->dither.count, 12345678913579<<ch, s->out_sample_fmt, s->int_sample_fmt);
-            av_assert0(s->dither.ch_count == preout->ch_count);
+                for(ch=0; ch<s->dither.noise.ch_count; ch++)
+                    swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, 12345678913579<<ch, s->out_sample_fmt, s->int_sample_fmt);
+            av_assert0(s->dither.noise.ch_count == preout->ch_count);
 
 
-            if(s->dither_pos + out_count > s->dither.count)
-                s->dither_pos = 0;
+            if(s->dither.dither_pos + out_count > s->dither.noise.count)
+                s->dither.dither_pos = 0;
 
 
-            if (s->dither_method < SWR_DITHER_NS){
+            if (s->dither.method < SWR_DITHER_NS){
                 if (s->mix_2_1_simd) {
                     int len1= out_count&~15;
                     int off = len1 * preout->bps;
 
                     if(len1)
                         for(ch=0; ch<preout->ch_count; ch++)
                 if (s->mix_2_1_simd) {
                     int len1= out_count&~15;
                     int off = len1 * preout->bps;
 
                     if(len1)
                         for(ch=0; ch<preout->ch_count; ch++)
-                            s->mix_2_1_simd(preout->ch[ch], preout->ch[ch], s->dither.ch[ch] + s->dither.bps * s->dither_pos, s->native_one, 0, 0, len1);
+                            s->mix_2_1_simd(preout->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.dither_pos, s->native_one, 0, 0, len1);
                     if(out_count != len1)
                         for(ch=0; ch<preout->ch_count; ch++)
                     if(out_count != len1)
                         for(ch=0; ch<preout->ch_count; ch++)
-                            s->mix_2_1_f(preout->ch[ch] + off, preout->ch[ch] + off, s->dither.ch[ch] + s->dither.bps * s->dither_pos + off + len1, s->native_one, 0, 0, out_count - len1);
+                            s->mix_2_1_f(preout->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.dither_pos + off + len1, s->native_one, 0, 0, out_count - len1);
                 } else {
                     for(ch=0; ch<preout->ch_count; ch++)
                 } else {
                     for(ch=0; ch<preout->ch_count; ch++)
-                        s->mix_2_1_f(preout->ch[ch], preout->ch[ch], s->dither.ch[ch] + s->dither.bps * s->dither_pos, s->native_one, 0, 0, out_count);
+                        s->mix_2_1_f(preout->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.dither_pos, s->native_one, 0, 0, out_count);
                 }
             } else {
                 switch(s->int_sample_fmt) {
                 }
             } else {
                 switch(s->int_sample_fmt) {
-                case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, preout, &s->dither, out_count); break;
-                case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, preout, &s->dither, out_count); break;
-                case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, preout, &s->dither, out_count); break;
-                case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,preout, &s->dither, out_count); break;
+                case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, preout, &s->dither.noise, out_count); break;
+                case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, preout, &s->dither.noise, out_count); break;
+                case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, preout, &s->dither.noise, out_count); break;
+                case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,preout, &s->dither.noise, out_count); break;
                 }
             }
                 }
             }
-            s->dither_pos += out_count;
+            s->dither.dither_pos += out_count;
         }
 //FIXME packed doesnt need more than 1 chan here!
         swri_audio_convert(s->out_convert, out, preout, out_count);
         }
 //FIXME packed doesnt need more than 1 chan here!
         swri_audio_convert(s->out_convert, out, preout, out_count);
index 986eecc..9276b5c 100644 (file)
@@ -50,6 +50,19 @@ typedef struct AudioData{
     enum AVSampleFormat fmt;    ///< sample format
 } AudioData;
 
     enum AVSampleFormat fmt;    ///< sample format
 } AudioData;
 
+struct DitherContext {
+    enum SwrDitherType method;
+    int dither_pos;
+    float scale;
+    int ns_taps;                                    ///< Noise shaping dither taps
+    float ns_scale;                                 ///< Noise shaping dither scale
+    float ns_scale_1;                               ///< Noise shaping dither scale^-1
+    int ns_pos;                                     ///< Noise shaping dither position
+    float ns_coeffs[NS_TAPS];                       ///< Noise shaping filter coefficients
+    float ns_errors[SWR_CH_MAX][2*NS_TAPS];
+    AudioData noise;                                ///< noise used for dithering
+};
+
 struct SwrContext {
     const AVClass *av_class;                        ///< AVClass used for AVOption and av_log()
     int log_level_offset;                           ///< logging level offset
 struct SwrContext {
     const AVClass *av_class;                        ///< AVClass used for AVOption and av_log()
     int log_level_offset;                           ///< logging level offset
@@ -70,15 +83,8 @@ struct SwrContext {
     const int *channel_map;                         ///< channel index (or -1 if muted channel) map
     int used_ch_count;                              ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
     enum SwrEngine engine;
     const int *channel_map;                         ///< channel index (or -1 if muted channel) map
     int used_ch_count;                              ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count)
     enum SwrEngine engine;
-    enum SwrDitherType dither_method;
-    int dither_pos;
-    float dither_scale;
-    int ns_taps;                                    ///< Noise shaping dither taps
-    float ns_scale;                                 ///< Noise shaping dither scale
-    float ns_scale_1;                               ///< Noise shaping dither scale^-1
-    int ns_pos;                                     ///< Noise shaping dither position
-    float ns_coeffs[NS_TAPS];                       ///< Noise shaping filter coefficients
-    float ns_errors[SWR_CH_MAX][2*NS_TAPS];
+
+    struct DitherContext dither;
 
     int filter_size;                                /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
     int phase_shift;                                /**< log2 of the number of entries in the resampling polyphase filterbank */
 
     int filter_size;                                /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
     int phase_shift;                                /**< log2 of the number of entries in the resampling polyphase filterbank */
@@ -105,7 +111,6 @@ struct SwrContext {
     AudioData preout;                               ///< pre-output audio data: used for rematrix/resample
     AudioData out;                                  ///< converted output audio data
     AudioData in_buffer;                            ///< cached audio data (convert and resample purpose)
     AudioData preout;                               ///< pre-output audio data: used for rematrix/resample
     AudioData out;                                  ///< converted output audio data
     AudioData in_buffer;                            ///< cached audio data (convert and resample purpose)
-    AudioData dither;                               ///< noise used for dithering
     int in_buffer_index;                            ///< cached buffer position
     int in_buffer_count;                            ///< cached buffer length
     int resample_in_constraint;                     ///< 1 if the input end was reach before the output end, 0 otherwise
     int in_buffer_index;                            ///< cached buffer position
     int in_buffer_count;                            ///< cached buffer length
     int resample_in_constraint;                     ///< 1 if the input end was reach before the output end, 0 otherwise