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

volume_neon: ARM NEON software amplification

parent 7a05ff18
...@@ -18,6 +18,11 @@ libchroma_yuv_neon_plugin_la_CFLAGS = $(AM_CFLAGS) ...@@ -18,6 +18,11 @@ libchroma_yuv_neon_plugin_la_CFLAGS = $(AM_CFLAGS)
libchroma_yuv_neon_plugin_la_LIBADD = $(AM_LIBADD) libchroma_yuv_neon_plugin_la_LIBADD = $(AM_LIBADD)
libchroma_yuv_neon_plugin_la_DEPENDENCIES = libchroma_yuv_neon_plugin_la_DEPENDENCIES =
libvolume_neon_plugin_la_SOURCES = volume.c amplify.S
libvolume_neon_plugin_la_CFLAGS = $(AM_CFLAGS)
libvolume_neon_plugin_la_LIBADD = $(AM_LIBADD)
libvolume_neon_plugin_la_DEPENDENCIES =
libyuv_rgb_neon_plugin_la_SOURCES = \ libyuv_rgb_neon_plugin_la_SOURCES = \
i420_rgb.S \ i420_rgb.S \
nv21_rgb.S \ nv21_rgb.S \
...@@ -30,5 +35,6 @@ libyuv_rgb_neon_plugin_la_DEPENDENCIES = ...@@ -30,5 +35,6 @@ libyuv_rgb_neon_plugin_la_DEPENDENCIES =
libvlc_LTLIBRARIES += \ libvlc_LTLIBRARIES += \
libaudio_format_neon_plugin.la \ libaudio_format_neon_plugin.la \
libchroma_yuv_neon_plugin.la \ libchroma_yuv_neon_plugin.la \
libvolume_neon_plugin.la \
libyuv_rgb_neon_plugin.la \ libyuv_rgb_neon_plugin.la \
$(NULL) $(NULL)
@*****************************************************************************
@ amplify.S : ARM NEON software amplification
@*****************************************************************************
@ Copyright (C) 2012 Rémi Denis-Courmont
@
@ This program is free software; you can redistribute it and/or modify
@ it under the terms of the GNU Lesser General Public License as published by
@ the Free Software Foundation; either version 2.1 of the License, or
@ (at your option) any later version.
@
@ This program is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ GNU Lesser General Public License for more details.
@
@ You should have received a copy of the GNU Lesser General Public License
@ along with this program; if not, write to the Free Software Foundation,
@ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
@****************************************************************************/
.syntax unified
.arm
.fpu neon
.text
#define DST r0
#define SRC r1
#define SIZE r2
.align 2
.global amplify_float_arm_neon
.type amplify_float_arm_neon, %function
amplify_float_arm_neon:
cmp SIZE, #0
bxeq lr
#ifdef __ARM_PCS
vmov s0, r3 @ softfp
#endif
pld [SRC, #64]
vld1.f32 {d16-d17}, [SRC,:128]!
subs SIZE, SIZE, #16
vmul.f32 d16, d16, d0[0]
vmul.f32 d17, d17, d0[0]
blo 5f
pld [SRC, #64]
vld1.f32 {d18-d19}, [SRC,:128]!
subs SIZE, SIZE, #16
vmul.f32 d18, d18, d0[0]
vmul.f32 d19, d19, d0[0]
blo 2f
1: @ main loop starts
pld [SRC, #64]
vld1.f32 {d20-d21}, [SRC,:128]!
subs SIZE, SIZE, #16
vmul.f32 d20, d20, d0[0]
vmul.f32 d21, d21, d0[0]
vst1.f32 {d16-d17}, [DST,:128]!
blo 3f
pld [SRC, #64]
vld1.f32 {d16-d17}, [SRC,:128]!
subs SIZE, SIZE, #16
vmul.f32 d16, d16, d0[0]
vmul.f32 d17, d17, d0[0]
vst1.f32 {d18-d19}, [DST,:128]!
blo 4f
pld [SRC, #64]
vld1.f32 {d18-d19}, [SRC,:128]!
subs SIZE, SIZE, #16
vmul.f32 d18, d18, d0[0]
vmul.f32 d19, d19, d0[0]
vst1.f32 {d20-d21}, [DST,:128]!
bhi 1b
@ main loop ends
2: vst1.f32 {d16-d17}, [DST,:128]!
vst1.f32 {d18-d19}, [DST,:128]!
bx lr
3: vst1.f32 {d18-d19}, [DST,:128]!
vst1.f32 {d20-d21}, [DST,:128]!
bx lr
4: vst1.f32 {d20-d21}, [DST,:128]!
5: vst1.f32 {d16-d17}, [DST,:128]!
bx lr
/*****************************************************************************
* volume.c : ARM NEON audio volume
*****************************************************************************
* Copyright (C) 2012 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_cpu.h>
#include <vlc_aout.h>
#include <vlc_aout_volume.h>
static int Probe(vlc_object_t *);
vlc_module_begin()
set_category(CAT_AUDIO)
set_subcategory(SUBCAT_AUDIO_MISC)
set_description(N_("ARM NEON audio volume"))
set_capability("audio volume", 10)
set_callbacks(Probe, NULL)
vlc_module_end()
static void AmplifyFloat(audio_volume_t *, block_t *, float);
static int Probe(vlc_object_t *obj)
{
audio_volume_t *volume = (audio_volume_t *)obj;
if (!vlc_CPU_ARM_NEON())
return VLC_EGENERIC;
if (volume->format == VLC_CODEC_FL32)
volume->amplify = AmplifyFloat;
else
return VLC_EGENERIC;
return VLC_SUCCESS;
}
void amplify_float_arm_neon(float *, const float *, size_t, float);
static void AmplifyFloat(audio_volume_t *volume, block_t *block, float amp)
{
float *buf = (float *)block->p_buffer;
size_t length = block->i_buffer;
if (amp == 1.0)
return;
/* Unaligned header */
assert(((uintptr_t)buf & 3) == 0);
while (unlikely((uintptr_t)buf & 12))
{
*(buf++) *= amp;
length -= 4;
}
/* Unaligned footer */
assert((length & 3) == 0);
while (unlikely(length & 12))
{
length -= 4;
buf[length / 4] *= amp;
}
amplify_float_arm_neon(buf, buf, length, amp);
(void) volume;
}
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