linuxsampler 1.0.0

AudioChannel.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   LinuxSampler - modular, streaming capable sampler                     *
00004  *                                                                         *
00005  *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
00006  *   Copyright (C) 2005 - 2009 Christian Schoenebeck                       *
00007  *                                                                         *
00008  *   This program is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This program is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this program; if not, write to the Free Software           *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
00022  ***************************************************************************/
00023 
00024 #include "AudioChannel.h"
00025 
00026 #include "../../common/global_private.h"
00027 #include "../../common/Thread.h" // needed for allocAlignedMem() and freeAlignedMem()
00028 
00029 #if defined(__APPLE__)
00030 # include <stdlib.h>
00031 #else
00032 # include <malloc.h>
00033 #endif
00034 
00035 
00036 namespace LinuxSampler {
00037 
00044     AudioChannel::AudioChannel(uint ChannelNr, uint BufferSize) {
00045         this->ChannelNr          = ChannelNr;
00046         this->pBuffer            = (float *) Thread::allocAlignedMem(16,BufferSize*sizeof(float));
00047         this->uiBufferSize       = BufferSize;
00048         this->pMixChannel        = NULL;
00049         this->UsesExternalBuffer = false;
00050 
00051         Parameters["NAME"]           = new ParameterName("Channel " + ToString(ChannelNr));
00052         Parameters["IS_MIX_CHANNEL"] = new ParameterIsMixChannel(false);
00053 
00054         Clear();
00055     }
00056 
00064     AudioChannel::AudioChannel(uint ChannelNr, float* pBuffer, uint BufferSize) {
00065         this->ChannelNr          = ChannelNr;
00066         this->pBuffer            = pBuffer;
00067         this->uiBufferSize       = BufferSize;
00068         this->pMixChannel        = NULL;
00069         this->UsesExternalBuffer = true;
00070 
00071         Parameters["NAME"]           = new ParameterName("Channel " + ToString(ChannelNr));
00072         Parameters["IS_MIX_CHANNEL"] = new ParameterIsMixChannel(false);
00073 
00074         Clear();
00075     }
00076 
00084     AudioChannel::AudioChannel(uint ChannelNr, AudioChannel* pMixChannelDestination) {
00085         this->ChannelNr          = ChannelNr;
00086         this->pBuffer            = pMixChannelDestination->Buffer();
00087         this->uiBufferSize       = pMixChannelDestination->uiBufferSize;
00088         this->pMixChannel        = pMixChannelDestination;
00089         this->UsesExternalBuffer = true;
00090 
00091         Parameters["NAME"]           = new ParameterName("Channel " + ToString(ChannelNr));
00092         Parameters["IS_MIX_CHANNEL"] = new ParameterIsMixChannel(true);
00093         //TODO: Parameters["MIX_CHANNEL_DESTINATION"] = new ParameterMixChannelDestination(dest_chan);
00094 
00095         Clear();
00096     }
00097 
00101     AudioChannel::~AudioChannel() {
00102         std::map<String,DeviceRuntimeParameter*>::iterator iter = Parameters.begin();
00103         while (iter != Parameters.end()) { delete iter->second; iter++; }
00104         if (!UsesExternalBuffer) Thread::freeAlignedMem(pBuffer);
00105     }
00106 
00117     void AudioChannel::CopyTo(AudioChannel* pDst, const uint Samples) {
00118         memcpy(pDst->Buffer(), Buffer(), Samples * sizeof(float));
00119     }
00120 
00133     void AudioChannel::CopyTo(AudioChannel* pDst, const uint Samples, const float fLevel) {
00134         if (fLevel == 1.0f) CopyTo(pDst, Samples);
00135         else {
00136             float* pSrcBuf = Buffer();
00137             float* pDstBuf = pDst->Buffer();
00138             #if HAVE_GCC_VECTOR_EXTENSIONS
00139             if ((size_t)pSrcBuf % 16 == 0 && (size_t)pDstBuf % 16 == 0) {
00140                 const v4sf vcoeff = { fLevel, fLevel, fLevel, fLevel };
00141                 const v4sf* src = static_cast<v4sf*>((void*)Buffer());
00142                 v4sf* dst       = static_cast<v4sf*>((void*)pDst->Buffer());
00143                 const int cells = Samples / 4;
00144                 for (int i = 0; i < cells; ++i)
00145                     dst[i] = src[i] * vcoeff;
00146             } else {
00147             #endif
00148                 for (int i = 0; i < Samples; i++)
00149                     pDstBuf[i] = pSrcBuf[i] * fLevel;
00150             #if HAVE_GCC_VECTOR_EXTENSIONS
00151             }
00152             #endif
00153         }
00154     }
00155 
00163     void AudioChannel::MixTo(AudioChannel* pDst, const uint Samples) {
00164         float* pSrcBuf = Buffer();
00165         float* pDstBuf = pDst->Buffer();
00166         #if HAVE_GCC_VECTOR_EXTENSIONS
00167         if ((size_t)pSrcBuf % 16 == 0 && (size_t)pDstBuf % 16 == 0) {
00168             const v4sf* src = static_cast<v4sf*>((void*)Buffer());
00169             v4sf* dst       = static_cast<v4sf*>((void*)pDst->Buffer());
00170             const int cells = Samples / 4;
00171             for (int i = 0; i < cells; ++i)
00172                 dst[i] += src[i];
00173         } else {
00174         #endif
00175             for (int i = 0; i < Samples; i++)
00176                 pDstBuf[i] += pSrcBuf[i];
00177         #if HAVE_GCC_VECTOR_EXTENSIONS
00178         }
00179         #endif
00180     }
00181 
00191     void AudioChannel::MixTo(AudioChannel* pDst, const uint Samples, const float fLevel) {
00192         if (fLevel == 1.0f) MixTo(pDst, Samples);
00193         else {
00194             float* pSrcBuf = Buffer();
00195             float* pDstBuf = pDst->Buffer();
00196             #if HAVE_GCC_VECTOR_EXTENSIONS
00197             if ((size_t)pSrcBuf % 16 == 0 && (size_t)pDstBuf % 16 == 0) {
00198                 const v4sf vcoeff = { fLevel, fLevel, fLevel, fLevel };
00199                 const v4sf* src = static_cast<v4sf*>((void*)Buffer());
00200                 v4sf* dst       = static_cast<v4sf*>((void*)pDst->Buffer());
00201                 const int cells = Samples / 4;
00202                 for (int i = 0; i < cells; ++i)
00203                     dst[i] += src[i] * vcoeff;
00204             } else {
00205             #endif
00206                 for (int i = 0; i < Samples; i++)
00207                     pDstBuf[i] += pSrcBuf[i] * fLevel;
00208             #if HAVE_GCC_VECTOR_EXTENSIONS
00209             }
00210             #endif
00211         }
00212     }
00213 
00214     std::map<String,DeviceRuntimeParameter*> AudioChannel::ChannelParameters() {
00215         return Parameters;
00216     }
00217 }