[vlc-devel] commit: NEON vectorized fi32->s16l audio filter ( Rémi Denis-Courmont )
git version control
git at videolan.org
Sun Sep 6 12:55:48 CEST 2009
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Sep 5 22:12:36 2009 +0300| [1c8f5cc6a97717d9e1b38cd5c980c413bdb7e972] | committer: Rémi Denis-Courmont
NEON vectorized fi32->s16l audio filter
This conversion is always needed between mixer and output.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1c8f5cc6a97717d9e1b38cd5c980c413bdb7e972
---
modules/audio_filter/converter/neon.c | 81 ++++++++++++++++++++++++++++++---
1 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/modules/audio_filter/converter/neon.c b/modules/audio_filter/converter/neon.c
index 45a2a62..3b41e2c 100644
--- a/modules/audio_filter/converter/neon.c
+++ b/modules/audio_filter/converter/neon.c
@@ -37,6 +37,8 @@ vlc_module_end ()
static void Do_F32_S32 (aout_instance_t *, aout_filter_t *,
aout_buffer_t *, aout_buffer_t *);
+static void Do_S32_S16 (aout_instance_t *, aout_filter_t *,
+ aout_buffer_t *, aout_buffer_t *);
static int Open (vlc_object_t *obj)
{
@@ -47,15 +49,32 @@ static int Open (vlc_object_t *obj)
if (!AOUT_FMTS_SIMILAR (&filter->input, &filter->output))
return VLC_EGENERIC;
- if (filter->input.i_format == VLC_CODEC_FL32)
+ switch (filter->input.i_format)
{
- if (filter->output.i_format == VLC_CODEC_FI32)
- filter->pf_do_work = Do_F32_S32;
- else
+ case VLC_CODEC_FL32:
+ switch (filter->output.i_format)
+ {
+ case VLC_CODEC_FI32:
+ filter->pf_do_work = Do_F32_S32;
+ break;
+ default:
+ return VLC_EGENERIC;
+ }
+ break;
+
+ case VLC_CODEC_FI32:
+ switch (filter->output.i_format)
+ {
+ case VLC_CODEC_S16N:
+ filter->pf_do_work = Do_S32_S16;
+ break;
+ default:
+ return VLC_EGENERIC;
+ }
+ break;
+ default:
return VLC_EGENERIC;
}
- else
- return VLC_EGENERIC;
filter->b_in_place = true;
return 0;
@@ -118,3 +137,53 @@ static void Do_F32_S32 (aout_instance_t *aout, aout_filter_t *filter,
outbuf->i_nb_bytes = inbuf->i_nb_bytes;
(void) aout;
}
+
+/**
+ * Signed 32-bits fixed point to signed 16-bits integer
+ */
+static void Do_S32_S16 (aout_instance_t *aout, aout_filter_t *filter,
+ aout_buffer_t *inbuf, aout_buffer_t *outbuf)
+{
+ unsigned nb_samples = inbuf->i_nb_samples
+ * aout_FormatNbChannels (&filter->input);
+ int32_t *inp = (int32_t *)inbuf->p_buffer;
+ const int32_t *endp = inp + nb_samples;
+ int16_t *outp = (int16_t *)outbuf->p_buffer;
+
+ while (nb_samples & 3)
+ {
+ const int16_t roundup = 1 << 12;
+ asm volatile (
+ "qadd r0, %[inv], %[roundup]\n"
+ "ssat %[outv], #16, r0, asr #13\n"
+ : [outv] "=r" (*outp)
+ : [inv] "r" (*inp), [roundup] "r" (roundup)
+ : "r0");
+ inp++;
+ outp++;
+ nb_samples--;
+ }
+
+ if (nb_samples & 4)
+ asm volatile (
+ "vld1.s32 {q0}, [%[inp]]!\n"
+ "vrshrn.i32 d0, q0, #13\n"
+ "vst1.s16 {d0}, [%[outp]]!\n"
+ : [outp] "+r" (outp), [inp] "+r" (inp)
+ :
+ : "q0", "memory");
+
+ while (inp != endp)
+ asm volatile (
+ "vld1.s32 {q0-q1}, [%[inp]]!\n"
+ "vrshrn.s32 d0, q0, #13\n"
+ "vrshrn.s32 d1, q1, #13\n"
+ "vst1.s16 {q0}, [%[outp]]!\n"
+ : [outp] "+r" (outp), [inp] "+r" (inp)
+ :
+ : "q0", "q1", "memory");
+
+ outbuf->i_nb_samples = inbuf->i_nb_samples;
+ outbuf->i_nb_bytes = inbuf->i_nb_bytes / 2;
+ (void) aout;
+}
More information about the vlc-devel
mailing list