]> git.sesse.net Git - mlt/blobdiff - src/modules/core/filter_audioconvert.c
Fix reading binary files on Windows.
[mlt] / src / modules / core / filter_audioconvert.c
index d1f7cb33bb416cfc4dbe5d903230b9ca366dca69..ad1e943375d5c0dd2c91089ee34d9ba892bbf28e 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
+#ifndef CLAMP
+#define CLAMP( x, min, max ) (x) < (min) ? (min) : (x) > (max) ? (max) : (x)
+#endif
+
 static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *format, mlt_audio_format requested_format )
 {
        int error = 1;
@@ -102,13 +106,24 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                while ( --i )
                                {
                                        float f = (float)( *q++ ) / 32768.0;
-                                       f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
-                                       *p++ = f;
+                                       *p++ = CLAMP( f, -1.0f, 1.0f );
                                }
                                *audio = buffer;
                                error = 0;
                                break;
                        }
+                       case mlt_audio_u8:
+                       {
+                               uint8_t *buffer = mlt_pool_alloc( size );
+                               uint8_t *p = buffer;
+                               int16_t *q = (int16_t*) *audio;
+                               int i = samples * channels + 1;
+                               while ( --i )
+                                       *p++ = ( *q++ >> 8 ) + 128;
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
                        default:
                                break;
                        }
@@ -164,13 +179,25 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                        for ( c = 0; c < channels; c++ )
                                        {
                                                float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
-                                               f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
-                                               *p++ = f;
+                                               *p++ = CLAMP( f, -1.0f, 1.0f );
                                        }
                                *audio = buffer;
                                error = 0;
                                break;
                        }
+                       case mlt_audio_u8:
+                       {
+                               uint8_t *buffer = mlt_pool_alloc( size );
+                               uint8_t *p = buffer;
+                               int32_t *q = (int32_t*) *audio;
+                               int s, c;
+                               for ( s = 0; s < samples; s++ )
+                                       for ( c = 0; c < channels; c++ )
+                                               *p++ = ( q[c * samples + s] >> 24 ) + 128;
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
                        default:
                                break;
                        }
@@ -188,7 +215,7 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                        for ( c = 0; c < channels; c++ )
                                        {
                                                float f = *( q + c * samples + s );
-                                               f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+                                               f = CLAMP( f, -1.0f, 1.0f );
                                                *p++ = 32767 * f;
                                        }
                                *audio = buffer;
@@ -204,8 +231,9 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                while ( --i )
                                {
                                        float f = *q++;
-                                       f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
-                                       *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
+                                       f = CLAMP( f, -1.0f, 1.0f );
+                                       int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
+                                       *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
                                }
                                *audio = buffer;
                                error = 0;
@@ -221,8 +249,9 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                        for ( c = 0; c < channels; c++ )
                                        {
                                                float f = *( q + c * samples + s );
-                                               f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
-                                               *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
+                                               f = CLAMP( f, -1.0f, 1.0f );
+                                               int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
+                                               *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
                                        }
                                *audio = buffer;
                                error = 0;
@@ -241,6 +270,23 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                error = 0;
                                break;
                        }
+                       case mlt_audio_u8:
+                       {
+                               uint8_t *buffer = mlt_pool_alloc( size );
+                               uint8_t *p = buffer;
+                               float *q = (float*) *audio;
+                               int s, c;
+                               for ( s = 0; s < samples; s++ )
+                                       for ( c = 0; c < channels; c++ )
+                                       {
+                                               float f = *( q + c * samples + s );
+                                               f = CLAMP( f, -1.0f, 1.0f );
+                                               *p++ = ( 127 * f ) + 128;
+                                       }
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
                        default:
                                break;
                        }
@@ -310,6 +356,18 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                error = 0;
                                break;
                        }
+                       case mlt_audio_u8:
+                       {
+                               uint8_t *buffer = mlt_pool_alloc( size );
+                               uint8_t *p = buffer;
+                               int32_t *q = (int32_t*) *audio;
+                               int i = samples * channels + 1;
+                               while ( --i )
+                                       *p++ = ( *q++ >> 24 ) + 128;
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
                        default:
                                break;
                        }
@@ -326,7 +384,7 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                while ( --i )
                                {
                                        float f = *q++;
-                                       f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
+                                       f = CLAMP( f, -1.0f , 1.0f );
                                        *p++ = 32767 * f;
                                }
                                *audio = buffer;
@@ -364,8 +422,9 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                        while ( --i )
                                        {
                                                float f = *q;
-                                               f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
-                                               *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
+                                               f = CLAMP( f, -1.0f , 1.0f );
+                                               int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
+                                               *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
                                                q += channels;
                                        }
                                }
@@ -382,8 +441,109 @@ static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *forma
                                while ( --i )
                                {
                                        float f = *q++;
-                                       f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
-                                       *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
+                                       f = CLAMP( f, -1.0f , 1.0f );
+                                       int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
+                                       *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
+                               }
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
+                       case mlt_audio_u8:
+                       {
+                               uint8_t *buffer = mlt_pool_alloc( size );
+                               uint8_t *p = buffer;
+                               float *q = (float*) *audio;
+                               int i = samples * channels + 1;
+                               while ( --i )
+                               {
+                                       float f = *q++;
+                                       f = CLAMP( f, -1.0f , 1.0f );
+                                       *p++ = ( 127 * f ) + 128;
+                               }
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
+                       default:
+                               break;
+                       }
+                       break;
+               case mlt_audio_u8:
+                       switch ( requested_format )
+                       {
+                       case mlt_audio_s32:
+                       {
+                               int32_t *buffer = mlt_pool_alloc( size );
+                               int32_t *p = buffer;
+                               int c;
+                               for ( c = 0; c < channels; c++ )
+                               {
+                                       uint8_t *q = (uint8_t*) *audio + c;
+                                       int i = samples + 1;
+                                       while ( --i )
+                                       {
+                                               *p++ = ( (int32_t) *q - 128 ) << 24;
+                                               q += channels;
+                                       }
+                               }
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
+                       case mlt_audio_float:
+                       {
+                               float *buffer = mlt_pool_alloc( size );
+                               float *p = buffer;
+                               int c;
+                               for ( c = 0; c < channels; c++ )
+                               {
+                                       uint8_t *q = (uint8_t*) *audio + c;
+                                       int i = samples + 1;
+                                       while ( --i )
+                                       {
+                                               *p++ = ( (float) *q - 128 ) / 256.0f;
+                                               q += channels;
+                                       }
+                               }
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
+                       case mlt_audio_s16:
+                       {
+                               int16_t *buffer = mlt_pool_alloc( size );
+                               int16_t *p = buffer;
+                               uint8_t *q = (uint8_t*) *audio;
+                               int i = samples * channels + 1;
+                               while ( --i )
+                                       *p++ = ( (int16_t) *q++ - 128 ) << 8;
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
+                       case mlt_audio_s32le:
+                       {
+                               int32_t *buffer = mlt_pool_alloc( size );
+                               int32_t *p = buffer;
+                               uint8_t *q = (uint8_t*) *audio;
+                               int i = samples * channels + 1;
+                               while ( --i )
+                                       *p++ = ( (int32_t) *q++ - 128 ) << 24;
+                               *audio = buffer;
+                               error = 0;
+                               break;
+                       }
+                       case mlt_audio_f32le:
+                       {
+                               float *buffer = mlt_pool_alloc( size );
+                               float *p = buffer;
+                               uint8_t *q = (uint8_t*) *audio;
+                               int i = samples * channels + 1;
+                               while ( --i )
+                               {
+                                       float f = ( (float) *q++ - 128 ) / 256.0f;
+                                       *p++ = CLAMP( f, -1.0f, 1.0f );
                                }
                                *audio = buffer;
                                error = 0;
@@ -419,7 +579,7 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 
 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
 {
-       mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
+       mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
        if ( mlt_filter_init( this, this ) == 0 )
                this->process = filter_process;
        return this;