From 6d21b9448a0d337b449ce22f68802670c911ca40 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 22 Dec 2013 23:24:42 +0100 Subject: pcm/PcmVolume: rename to Volume.cxx --- Makefile.am | 2 +- src/MixerAll.cxx | 2 +- src/filter/ReplayGainFilterPlugin.cxx | 2 +- src/filter/VolumeFilterPlugin.cxx | 2 +- src/mixer/SoftwareMixerPlugin.cxx | 2 +- src/pcm/PcmMix.cxx | 2 +- src/pcm/PcmVolume.cxx | 178 ---------------------------------- src/pcm/PcmVolume.hxx | 87 ----------------- src/pcm/Volume.cxx | 178 ++++++++++++++++++++++++++++++++++ src/pcm/Volume.hxx | 87 +++++++++++++++++ test/read_mixer.cxx | 2 +- test/run_filter.cxx | 2 +- test/software_volume.cxx | 2 +- test/test_pcm_volume.cxx | 2 +- 14 files changed, 275 insertions(+), 275 deletions(-) delete mode 100644 src/pcm/PcmVolume.cxx delete mode 100644 src/pcm/PcmVolume.hxx create mode 100644 src/pcm/Volume.cxx create mode 100644 src/pcm/Volume.hxx diff --git a/Makefile.am b/Makefile.am index 93bc71351..767b4dcf2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -339,7 +339,7 @@ libpcm_a_SOURCES = \ src/pcm/dsd2pcm/dsd2pcm.c src/pcm/dsd2pcm/dsd2pcm.h \ src/pcm/PcmDsd.cxx src/pcm/PcmDsd.hxx \ src/pcm/PcmDsdUsb.cxx src/pcm/PcmDsdUsb.hxx \ - src/pcm/PcmVolume.cxx src/pcm/PcmVolume.hxx \ + src/pcm/Volume.cxx src/pcm/Volume.hxx \ src/pcm/PcmMix.cxx src/pcm/PcmMix.hxx \ src/pcm/PcmChannels.cxx src/pcm/PcmChannels.hxx \ src/pcm/PcmPack.cxx src/pcm/PcmPack.hxx \ diff --git a/src/MixerAll.cxx b/src/MixerAll.cxx index 37225fd25..2eb54c232 100644 --- a/src/MixerAll.cxx +++ b/src/MixerAll.cxx @@ -23,7 +23,7 @@ #include "MixerInternal.hxx" #include "MixerList.hxx" #include "OutputAll.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "OutputInternal.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" diff --git a/src/filter/ReplayGainFilterPlugin.cxx b/src/filter/ReplayGainFilterPlugin.cxx index b2dcde4cc..c6c3cc2aa 100644 --- a/src/filter/ReplayGainFilterPlugin.cxx +++ b/src/filter/ReplayGainFilterPlugin.cxx @@ -26,7 +26,7 @@ #include "ReplayGainInfo.hxx" #include "ReplayGainConfig.hxx" #include "MixerControl.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "pcm/PcmBuffer.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" diff --git a/src/filter/VolumeFilterPlugin.cxx b/src/filter/VolumeFilterPlugin.cxx index 1b663f6eb..2438e0336 100644 --- a/src/filter/VolumeFilterPlugin.cxx +++ b/src/filter/VolumeFilterPlugin.cxx @@ -22,7 +22,7 @@ #include "FilterPlugin.hxx" #include "FilterInternal.hxx" #include "FilterRegistry.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "pcm/PcmBuffer.hxx" #include "AudioFormat.hxx" #include "util/Error.hxx" diff --git a/src/mixer/SoftwareMixerPlugin.cxx b/src/mixer/SoftwareMixerPlugin.cxx index 193e68f23..e5f4b1659 100644 --- a/src/mixer/SoftwareMixerPlugin.cxx +++ b/src/mixer/SoftwareMixerPlugin.cxx @@ -24,7 +24,7 @@ #include "FilterRegistry.hxx" #include "FilterInternal.hxx" #include "filter/VolumeFilterPlugin.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "ConfigData.hxx" #include "util/Error.hxx" diff --git a/src/pcm/PcmMix.cxx b/src/pcm/PcmMix.cxx index ffe935a0f..caf7fe516 100644 --- a/src/pcm/PcmMix.cxx +++ b/src/pcm/PcmMix.cxx @@ -19,7 +19,7 @@ #include "config.h" #include "PcmMix.hxx" -#include "PcmVolume.hxx" +#include "Volume.hxx" #include "PcmUtils.hxx" #include "AudioFormat.hxx" #include "Traits.hxx" diff --git a/src/pcm/PcmVolume.cxx b/src/pcm/PcmVolume.cxx deleted file mode 100644 index 5c0a1fbd3..000000000 --- a/src/pcm/PcmVolume.cxx +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2003-2013 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU 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. - */ - -#include "config.h" -#include "PcmVolume.hxx" -#include "PcmUtils.hxx" -#include "Traits.hxx" -#include "AudioFormat.hxx" - -#include -#include - -template> -static void -pcm_volume_change(typename Traits::pointer_type buffer, - typename Traits::const_pointer_type end, - int volume) -{ - while (buffer < end) { - typename Traits::long_type sample = *buffer; - - sample = (sample * volume + pcm_volume_dither() + - PCM_VOLUME_1S / 2) - >> PCM_VOLUME_BITS; - - *buffer++ = PcmClamp(sample); - } -} - -static void -pcm_volume_change_8(int8_t *buffer, const int8_t *end, int volume) -{ - pcm_volume_change(buffer, end, volume); -} - -static void -pcm_volume_change_16(int16_t *buffer, const int16_t *end, int volume) -{ - pcm_volume_change(buffer, end, volume); -} - -#ifdef __i386__ -/** - * Optimized volume function for i386. Use the EDX:EAX 2*32 bit - * multiplication result instead of emulating 64 bit multiplication. - */ -static inline int32_t -pcm_volume_sample_24(int32_t sample, int32_t volume, gcc_unused int32_t dither) -{ - int32_t result; - - asm(/* edx:eax = sample * volume */ - "imul %2\n" - - /* "add %3, %1\n" dithering disabled for now, because we - have no overflow check - is dithering really important - here? */ - - /* eax = edx:eax / PCM_VOLUME_1 */ - "sal $22, %%edx\n" - "shr $10, %1\n" - "or %%edx, %1\n" - - : "=a"(result) - : "0"(sample), "r"(volume) /* , "r"(dither) */ - : "edx" - ); - - return result; -} -#endif - -static void -pcm_volume_change_24(int32_t *buffer, const int32_t *end, int volume) -{ -#ifdef __i386__ - while (buffer < end) { - /* assembly version for i386 */ - int32_t sample = *buffer; - - sample = pcm_volume_sample_24(sample, volume, - pcm_volume_dither()); - } -#else - pcm_volume_change(buffer, end, volume); -#endif -} - -static void -pcm_volume_change_32(int32_t *buffer, const int32_t *end, int volume) -{ -#ifdef __i386__ - while (buffer < end) { - /* assembly version for i386 */ - int32_t sample = *buffer; - - *buffer++ = pcm_volume_sample_24(sample, volume, 0); - } -#else - pcm_volume_change(buffer, end, volume); -#endif -} - -static void -pcm_volume_change_float(float *buffer, const float *end, float volume) -{ - while (buffer < end) { - float sample = *buffer; - sample *= volume; - *buffer++ = sample; - } -} - -bool -pcm_volume(void *buffer, size_t length, - SampleFormat format, - int volume) -{ - if (volume == PCM_VOLUME_1S) - return true; - - if (volume <= 0) { - memset(buffer, 0, length); - return true; - } - - const void *end = pcm_end_pointer(buffer, length); - switch (format) { - case SampleFormat::UNDEFINED: - case SampleFormat::DSD: - /* not implemented */ - return false; - - case SampleFormat::S8: - pcm_volume_change_8((int8_t *)buffer, (const int8_t *)end, - volume); - return true; - - case SampleFormat::S16: - pcm_volume_change_16((int16_t *)buffer, (const int16_t *)end, - volume); - return true; - - case SampleFormat::S24_P32: - pcm_volume_change_24((int32_t *)buffer, (const int32_t *)end, - volume); - return true; - - case SampleFormat::S32: - pcm_volume_change_32((int32_t *)buffer, (const int32_t *)end, - volume); - return true; - - case SampleFormat::FLOAT: - pcm_volume_change_float((float *)buffer, (const float *)end, - pcm_volume_to_float(volume)); - return true; - } - - assert(false); - gcc_unreachable(); -} diff --git a/src/pcm/PcmVolume.hxx b/src/pcm/PcmVolume.hxx deleted file mode 100644 index 52102a294..000000000 --- a/src/pcm/PcmVolume.hxx +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2003-2013 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU 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. - */ - -#ifndef MPD_PCM_VOLUME_HXX -#define MPD_PCM_VOLUME_HXX - -#include "PcmPrng.hxx" -#include "AudioFormat.hxx" - -#include -#include - -/** - * Number of fractional bits for a fixed-point volume value. - */ -static constexpr unsigned PCM_VOLUME_BITS = 10; - -/** - * This value means "100% volume". - */ -static constexpr unsigned PCM_VOLUME_1 = 1024; -static constexpr int PCM_VOLUME_1S = PCM_VOLUME_1; - -struct AudioFormat; - -/** - * Converts a float value (0.0 = silence, 1.0 = 100% volume) to an - * integer volume value (1000 = 100%). - */ -static inline int -pcm_float_to_volume(float volume) -{ - return volume * PCM_VOLUME_1 + 0.5; -} - -static inline float -pcm_volume_to_float(int volume) -{ - return (float)volume / (float)PCM_VOLUME_1; -} - -/** - * Returns the next volume dithering number, between -511 and +511. - * This number is taken from a global PRNG, see pcm_prng(). - */ -static inline int -pcm_volume_dither(void) -{ - static unsigned long state; - uint32_t r; - - r = state = pcm_prng(state); - - return (r & 511) - ((r >> 9) & 511); -} - -/** - * Adjust the volume of the specified PCM buffer. - * - * @param buffer the PCM buffer - * @param length the length of the PCM buffer - * @param format the sample format of the PCM buffer - * @param volume the volume between 0 and #PCM_VOLUME_1 - * @return true on success, false if the audio format is not supported - */ -bool -pcm_volume(void *buffer, size_t length, - SampleFormat format, - int volume); - -#endif diff --git a/src/pcm/Volume.cxx b/src/pcm/Volume.cxx new file mode 100644 index 000000000..eaba84a59 --- /dev/null +++ b/src/pcm/Volume.cxx @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +#include "config.h" +#include "Volume.hxx" +#include "PcmUtils.hxx" +#include "Traits.hxx" +#include "AudioFormat.hxx" + +#include +#include + +template> +static void +pcm_volume_change(typename Traits::pointer_type buffer, + typename Traits::const_pointer_type end, + int volume) +{ + while (buffer < end) { + typename Traits::long_type sample = *buffer; + + sample = (sample * volume + pcm_volume_dither() + + PCM_VOLUME_1S / 2) + >> PCM_VOLUME_BITS; + + *buffer++ = PcmClamp(sample); + } +} + +static void +pcm_volume_change_8(int8_t *buffer, const int8_t *end, int volume) +{ + pcm_volume_change(buffer, end, volume); +} + +static void +pcm_volume_change_16(int16_t *buffer, const int16_t *end, int volume) +{ + pcm_volume_change(buffer, end, volume); +} + +#ifdef __i386__ +/** + * Optimized volume function for i386. Use the EDX:EAX 2*32 bit + * multiplication result instead of emulating 64 bit multiplication. + */ +static inline int32_t +pcm_volume_sample_24(int32_t sample, int32_t volume, gcc_unused int32_t dither) +{ + int32_t result; + + asm(/* edx:eax = sample * volume */ + "imul %2\n" + + /* "add %3, %1\n" dithering disabled for now, because we + have no overflow check - is dithering really important + here? */ + + /* eax = edx:eax / PCM_VOLUME_1 */ + "sal $22, %%edx\n" + "shr $10, %1\n" + "or %%edx, %1\n" + + : "=a"(result) + : "0"(sample), "r"(volume) /* , "r"(dither) */ + : "edx" + ); + + return result; +} +#endif + +static void +pcm_volume_change_24(int32_t *buffer, const int32_t *end, int volume) +{ +#ifdef __i386__ + while (buffer < end) { + /* assembly version for i386 */ + int32_t sample = *buffer; + + sample = pcm_volume_sample_24(sample, volume, + pcm_volume_dither()); + } +#else + pcm_volume_change(buffer, end, volume); +#endif +} + +static void +pcm_volume_change_32(int32_t *buffer, const int32_t *end, int volume) +{ +#ifdef __i386__ + while (buffer < end) { + /* assembly version for i386 */ + int32_t sample = *buffer; + + *buffer++ = pcm_volume_sample_24(sample, volume, 0); + } +#else + pcm_volume_change(buffer, end, volume); +#endif +} + +static void +pcm_volume_change_float(float *buffer, const float *end, float volume) +{ + while (buffer < end) { + float sample = *buffer; + sample *= volume; + *buffer++ = sample; + } +} + +bool +pcm_volume(void *buffer, size_t length, + SampleFormat format, + int volume) +{ + if (volume == PCM_VOLUME_1S) + return true; + + if (volume <= 0) { + memset(buffer, 0, length); + return true; + } + + const void *end = pcm_end_pointer(buffer, length); + switch (format) { + case SampleFormat::UNDEFINED: + case SampleFormat::DSD: + /* not implemented */ + return false; + + case SampleFormat::S8: + pcm_volume_change_8((int8_t *)buffer, (const int8_t *)end, + volume); + return true; + + case SampleFormat::S16: + pcm_volume_change_16((int16_t *)buffer, (const int16_t *)end, + volume); + return true; + + case SampleFormat::S24_P32: + pcm_volume_change_24((int32_t *)buffer, (const int32_t *)end, + volume); + return true; + + case SampleFormat::S32: + pcm_volume_change_32((int32_t *)buffer, (const int32_t *)end, + volume); + return true; + + case SampleFormat::FLOAT: + pcm_volume_change_float((float *)buffer, (const float *)end, + pcm_volume_to_float(volume)); + return true; + } + + assert(false); + gcc_unreachable(); +} diff --git a/src/pcm/Volume.hxx b/src/pcm/Volume.hxx new file mode 100644 index 000000000..52102a294 --- /dev/null +++ b/src/pcm/Volume.hxx @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2003-2013 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +#ifndef MPD_PCM_VOLUME_HXX +#define MPD_PCM_VOLUME_HXX + +#include "PcmPrng.hxx" +#include "AudioFormat.hxx" + +#include +#include + +/** + * Number of fractional bits for a fixed-point volume value. + */ +static constexpr unsigned PCM_VOLUME_BITS = 10; + +/** + * This value means "100% volume". + */ +static constexpr unsigned PCM_VOLUME_1 = 1024; +static constexpr int PCM_VOLUME_1S = PCM_VOLUME_1; + +struct AudioFormat; + +/** + * Converts a float value (0.0 = silence, 1.0 = 100% volume) to an + * integer volume value (1000 = 100%). + */ +static inline int +pcm_float_to_volume(float volume) +{ + return volume * PCM_VOLUME_1 + 0.5; +} + +static inline float +pcm_volume_to_float(int volume) +{ + return (float)volume / (float)PCM_VOLUME_1; +} + +/** + * Returns the next volume dithering number, between -511 and +511. + * This number is taken from a global PRNG, see pcm_prng(). + */ +static inline int +pcm_volume_dither(void) +{ + static unsigned long state; + uint32_t r; + + r = state = pcm_prng(state); + + return (r & 511) - ((r >> 9) & 511); +} + +/** + * Adjust the volume of the specified PCM buffer. + * + * @param buffer the PCM buffer + * @param length the length of the PCM buffer + * @param format the sample format of the PCM buffer + * @param volume the volume between 0 and #PCM_VOLUME_1 + * @return true on success, false if the audio format is not supported + */ +bool +pcm_volume(void *buffer, size_t length, + SampleFormat format, + int volume); + +#endif diff --git a/test/read_mixer.cxx b/test/read_mixer.cxx index 8426443ae..07ff931c8 100644 --- a/test/read_mixer.cxx +++ b/test/read_mixer.cxx @@ -21,7 +21,7 @@ #include "MixerControl.hxx" #include "MixerList.hxx" #include "FilterRegistry.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "GlobalEvents.hxx" #include "Main.hxx" #include "event/Loop.hxx" diff --git a/test/run_filter.cxx b/test/run_filter.cxx index 085fc256b..a35429bc8 100644 --- a/test/run_filter.cxx +++ b/test/run_filter.cxx @@ -25,7 +25,7 @@ #include "AudioFormat.hxx" #include "FilterPlugin.hxx" #include "FilterInternal.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "MixerControl.hxx" #include "stdbin.h" #include "util/Error.hxx" diff --git a/test/software_volume.cxx b/test/software_volume.cxx index 19a0be88c..b850217df 100644 --- a/test/software_volume.cxx +++ b/test/software_volume.cxx @@ -24,7 +24,7 @@ */ #include "config.h" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "AudioParser.hxx" #include "AudioFormat.hxx" #include "util/Error.hxx" diff --git a/test/test_pcm_volume.cxx b/test/test_pcm_volume.cxx index 764d8b127..fae937c30 100644 --- a/test/test_pcm_volume.cxx +++ b/test/test_pcm_volume.cxx @@ -18,7 +18,7 @@ */ #include "test_pcm_all.hxx" -#include "pcm/PcmVolume.hxx" +#include "pcm/Volume.hxx" #include "test_pcm_util.hxx" #include -- cgit v1.2.3