linuxsampler 1.0.0
|
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 }