diff --git a/include/MixHelpers.h b/include/MixHelpers.h new file mode 100644 index 000000000..5c24450a9 --- /dev/null +++ b/include/MixHelpers.h @@ -0,0 +1,53 @@ +/* + * MixHelpers.h - helper functions for mixing buffers + * + * Copyright (c) 2014 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _MIX_HELPERS_H +#define _MIX_HELPERS_H + +#include "lmms_basics.h" + +namespace MixHelpers +{ + +/*! \brief Add samples from src to dst */ +void add( sampleFrame* dst, const sampleFrame* src, int frames ); + + +/*! \brief Add samples from src multiplied by coeffSrc to dst */ +void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ); + + +/*! \brief Add samples from src multiplied by coeffSrcLeft/coeffSrcRight to dst */ +void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ); + +/*! \brief Multiply dst by coeffDst and add samples from src multiplied by coeffSrc */ +void multiplyAndAddMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffDst, float coeffSrc, int frames ); + +/*! \brief Multiply dst by coeffDst and add samples from srcLeft/srcRight multiplied by coeffSrc */ +void multiplyAndAddMultipliedJoined( sampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, float coeffDst, float coeffSrc, int frames ); + +} + +#endif + diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp new file mode 100644 index 000000000..346bf5cde --- /dev/null +++ b/src/core/MixHelpers.cpp @@ -0,0 +1,153 @@ +/* + * MixHelpers.cpp - helper functions for mixing buffers + * + * Copyright (c) 2014 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "MixHelpers.h" + + +namespace MixHelpers +{ + +/*! \brief Function for applying MIXOP on all sample frames */ +template +static inline void run( sampleFrame* dst, const sampleFrame* src, int frames, const MIXOP& OP ) +{ + for( int i = 0; i < frames; ++i ) + { + OP( dst[i], src[i] ); + } +} + +/*! \brief Function for applying MIXOP on all sample frames - split source */ +template +static inline void run( sampleFrame* dst, const sample_t* srcLeft, const sample_t* srcRight, int frames, const MIXOP& OP ) +{ + for( int i = 0; i < frames; ++i ) + { + const sampleFrame src = { srcLeft[i], srcRight[i] }; + OP( dst[i], src ); + } +} + + + +struct AddOp +{ + void operator()( sampleFrame& dst, const sampleFrame& src ) const + { + dst[0] += src[0]; + dst[1] += src[1]; + } +} ; + +void add( sampleFrame* dst, const sampleFrame* src, int frames ) +{ + run<>( dst, src, frames, AddOp() ); +} + + + +struct AddMultipliedOp +{ + AddMultipliedOp( float coeff ) : m_coeff( coeff ) { } + + void operator()( sampleFrame& dst, const sampleFrame& src ) const + { + dst[0] += src[0] * m_coeff; + dst[1] += src[1] * m_coeff; + } + + const float m_coeff; +} ; + + +void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames ) +{ + run<>( dst, src, frames, AddMultipliedOp(coeffSrc) ); +} + + + +struct AddMultipliedStereoOp +{ + AddMultipliedStereoOp( float coeffLeft, float coeffRight ) + { + m_coeffs[0] = coeffLeft; + m_coeffs[1] = coeffRight; + } + + void operator()( sampleFrame& dst, const sampleFrame& src ) const + { + dst[0] += src[0] * m_coeffs[0]; + dst[1] += src[1] * m_coeffs[1]; + } + + float m_coeffs[2]; +} ; + + +void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames ) +{ + + run<>( dst, src, frames, AddMultipliedStereoOp(coeffSrcLeft, coeffSrcRight) ); +} + + + + + +struct MultiplyAndAddMultipliedOp +{ + MultiplyAndAddMultipliedOp( float coeffDst, float coeffSrc ) + { + m_coeffs[0] = coeffDst; + m_coeffs[1] = coeffSrc; + } + + void operator()( sampleFrame& dst, const sampleFrame& src ) const + { + dst[0] = dst[0]*m_coeffs[0] + src[0]*m_coeffs[1]; + dst[1] = dst[1]*m_coeffs[0] + src[1]*m_coeffs[1]; + } + + float m_coeffs[2]; +} ; + + +void multiplyAndAddMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffDst, float coeffSrc, int frames ) +{ + run<>( dst, src, frames, MultiplyAndAddMultipliedOp(coeffDst, coeffSrc) ); +} + + + +void multiplyAndAddMultipliedJoined( sampleFrame* dst, + const sample_t* srcLeft, + const sample_t* srcRight, + float coeffDst, float coeffSrc, int frames ) +{ + run<>( dst, srcLeft, srcRight, frames, MultiplyAndAddMultipliedOp(coeffDst, coeffSrc) ); +} + +} +