Commit f58f22cc authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

volume: add direct support for S32N, FL64 and U8

parent 2c22b194
SOURCES_float32_mixer = float32.c libfloat_mixer_plugin_la_SOURCES = float.c
SOURCES_integer_mixer = integer.c libfloat_mixer_plugin_la_CFLAGS = $(AM_CFLAGS)
libfloat_mixer_plugin_la_LIBADD = $(AM_LIBADD) $(LIBM)
libinteger_mixer_plugin_la_SOURCES = integer.c
libinteger_mixer_plugin_la_CFLAGS = $(AM_CFLAGS)
libinteger_mixer_plugin_la_LIBADD = $(AM_LIBADD)
libvlc_LTLIBRARIES += \ libvlc_LTLIBRARIES += \
libfloat32_mixer_plugin.la \ libfloat_mixer_plugin.la \
libinteger_mixer_plugin.la libinteger_mixer_plugin.la
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int Create( vlc_object_t * ); static int Create( vlc_object_t * );
static void DoWork( audio_volume_t *, block_t *, float );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -53,31 +52,52 @@ vlc_module_begin () ...@@ -53,31 +52,52 @@ vlc_module_begin ()
vlc_module_end () vlc_module_end ()
/** /**
* Initializes the mixer * Mixes a new output buffer
*/ */
static int Create( vlc_object_t *p_this ) static void FilterFL32( audio_volume_t *p_volume, block_t *p_buffer,
float f_multiplier )
{ {
audio_volume_t *p_volume = (audio_volume_t *)p_this; if( f_multiplier == 1.f )
return; /* nothing to do */
if (p_volume->format != VLC_CODEC_FL32) float *p = (float *)p_buffer->p_buffer;
return -1; for( size_t i = p_buffer->i_buffer / sizeof(float); i > 0; i-- )
*(p++) *= f_multiplier;
p_volume->amplify = DoWork; (void) p_volume;
return 0;
} }
/** static void FilterFL64( audio_volume_t *p_volume, block_t *p_buffer,
* Mixes a new output buffer float f_multiplier )
*/
static void DoWork( audio_volume_t *p_volume, block_t *p_buffer,
float f_multiplier )
{ {
if( f_multiplier == 1.0 ) double *p = (double *)p_buffer->p_buffer;
double mult = f_multiplier;
if( mult == 1. )
return; /* nothing to do */ return; /* nothing to do */
float *p = (float *)p_buffer->p_buffer;
for( size_t i = p_buffer->i_buffer / sizeof(float); i > 0; i-- ) for( size_t i = p_buffer->i_buffer / sizeof(float); i > 0; i-- )
*(p++) *= f_multiplier; *(p++) *= mult;
(void) p_volume; (void) p_volume;
} }
/**
* Initializes the mixer
*/
static int Create( vlc_object_t *p_this )
{
audio_volume_t *p_volume = (audio_volume_t *)p_this;
switch (p_volume->format)
{
case VLC_CODEC_FL32:
p_volume->amplify = FilterFL32;
break;
case VLC_CODEC_FL64:
p_volume->amplify = FilterFL64;
break;
default:
return -1;
}
return 0;
}
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
# include "config.h" # include "config.h"
#endif #endif
#include <math.h>
#include <limits.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_aout.h> #include <vlc_aout.h>
...@@ -37,51 +40,92 @@ vlc_module_begin () ...@@ -37,51 +40,92 @@ vlc_module_begin ()
set_callbacks (Activate, NULL) set_callbacks (Activate, NULL)
vlc_module_end () vlc_module_end ()
static void FilterS16N (audio_volume_t *, block_t *, float); static void FilterS32N (audio_volume_t *vol, block_t *block, float volume)
static int Activate (vlc_object_t *obj)
{ {
audio_volume_t *vol = (audio_volume_t *)obj; int32_t *p = (int32_t *)block->p_buffer;
switch (vol->format) int32_t mult = lroundf (volume * 0x1.p24f);
if (mult == (1 << 24))
return;
for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--)
{ {
case VLC_CODEC_S16N: int64_t s = *p * (int64_t)mult;
vol->amplify = FilterS16N; if (s >= (INT32_MAX << INT64_C(24)))
break; *p = INT32_MAX;
default: else
return -1; if (s < (INT32_MIN << INT64_C(24)))
*p = INT32_MIN;
else
*p = s >> INT64_C(24);
p++;
} }
return 0; (void) vol;
} }
static void FilterS16N (audio_volume_t *vol, block_t *block, float volume) static void FilterS16N (audio_volume_t *vol, block_t *block, float volume)
{ {
int32_t mult = volume * 0x1.p16; int16_t *p = (int16_t *)block->p_buffer;
if (mult == 0x10000) int16_t mult = lroundf (volume * 0x1.p8f);
if (mult == (1 << 8))
return; return;
int16_t *p = (int16_t *)block->p_buffer; for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--)
if (mult < 0x10000)
{ {
for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--) int32_t s = *p * (int32_t)mult;
{ if (s >= (INT16_MAX << 8))
*p = (*p * mult) >> 16; *p = INT16_MAX;
p++; else
} if (s < (INT_MIN << 8))
*p = INT16_MIN;
else
*p = s >> 8;
p++;
} }
else (void) vol;
}
static void FilterU8 (audio_volume_t *vol, block_t *block, float volume)
{
uint8_t *p = (uint8_t *)block->p_buffer;
int16_t mult = lroundf (volume * 0x1.p8f);
if (mult == (1 << 8))
return;
for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--)
{ {
mult >>= 4; int32_t s = (*p - 128) * mult;
for (size_t n = block->i_buffer / sizeof (*p); n > 0; n--) if (s >= (INT8_MAX << 8))
{ *p = 255;
int32_t v = (*p * mult) >> 12; else
if (abs (v) > 0x7fff) if (s < (INT8_MIN << 8))
v = 0x8000; *p = 0;
*(p++) = v; else
} *p = (s >> 8) + 128;
p++;
} }
(void) vol; (void) vol;
} }
static int Activate (vlc_object_t *obj)
{
audio_volume_t *vol = (audio_volume_t *)obj;
switch (vol->format)
{
case VLC_CODEC_S32N:
vol->amplify = FilterS32N;
break;
case VLC_CODEC_S16N:
vol->amplify = FilterS16N;
break;
case VLC_CODEC_U8:
vol->amplify = FilterU8;
break;
default:
return -1;
}
return 0;
}
...@@ -318,7 +318,7 @@ modules/audio_filter/spatializer/revmodel.hpp ...@@ -318,7 +318,7 @@ modules/audio_filter/spatializer/revmodel.hpp
modules/audio_filter/spatializer/spatializer.cpp modules/audio_filter/spatializer/spatializer.cpp
modules/audio_filter/spatializer/tuning.h modules/audio_filter/spatializer/tuning.h
modules/audio_filter/stereo_widen.c modules/audio_filter/stereo_widen.c
modules/audio_mixer/float32.c modules/audio_mixer/float.c
modules/audio_mixer/integer.c modules/audio_mixer/integer.c
modules/audio_output/adummy.c modules/audio_output/adummy.c
modules/audio_output/alsa.c modules/audio_output/alsa.c
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment