Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2001-2003 Paul Davis 00003 Copyright (C) 2004-2008 Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU Lesser General Public License as published by 00007 the Free Software Foundation; either version 2.1 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 00019 */ 00020 00021 #include "JackPortType.h" 00022 #include <string.h> 00023 00024 #if defined (__APPLE__) 00025 #include <Accelerate/Accelerate.h> 00026 #elif defined (__SSE__) && !defined (__sun__) 00027 #include <xmmintrin.h> 00028 #endif 00029 00030 namespace Jack 00031 { 00032 00033 static void AudioBufferInit(void* buffer, size_t buffer_size, jack_nframes_t) 00034 { 00035 memset(buffer, 0, buffer_size); 00036 } 00037 00038 static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_t frames) 00039 { 00040 #ifdef __APPLE__ 00041 // It seems that a vector mult only operation does not exist... 00042 float gain = 1.0f; 00043 vDSP_vsma(buffer, 1, &gain, mixbuffer, 1, mixbuffer, 1, frames); 00044 #else 00045 jack_nframes_t frames_group = frames / 4; 00046 frames = frames % 4; 00047 00048 while (frames_group > 0) { 00049 #if defined (__SSE__) && !defined (__sun__) 00050 __m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer)); 00051 _mm_store_ps(mixbuffer, vec); 00052 00053 mixbuffer += 4; 00054 buffer += 4; 00055 frames_group--; 00056 #else 00057 register float mixFloat1 = *mixbuffer; 00058 register float sourceFloat1 = *buffer; 00059 register float mixFloat2 = *(mixbuffer + 1); 00060 register float sourceFloat2 = *(buffer + 1); 00061 register float mixFloat3 = *(mixbuffer + 2); 00062 register float sourceFloat3 = *(buffer + 2); 00063 register float mixFloat4 = *(mixbuffer + 3); 00064 register float sourceFloat4 = *(buffer + 3); 00065 00066 buffer += 4; 00067 frames_group--; 00068 00069 mixFloat1 += sourceFloat1; 00070 mixFloat2 += sourceFloat2; 00071 mixFloat3 += sourceFloat3; 00072 mixFloat4 += sourceFloat4; 00073 00074 *mixbuffer = mixFloat1; 00075 *(mixbuffer + 1) = mixFloat2; 00076 *(mixbuffer + 2) = mixFloat3; 00077 *(mixbuffer + 3) = mixFloat4; 00078 00079 mixbuffer += 4; 00080 #endif 00081 } 00082 00083 while (frames > 0) { 00084 register float mixFloat1 = *mixbuffer; 00085 register float sourceFloat1 = *buffer; 00086 buffer++; 00087 frames--; 00088 mixFloat1 += sourceFloat1; 00089 *mixbuffer = mixFloat1; 00090 mixbuffer++; 00091 } 00092 #endif 00093 } 00094 00095 static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) 00096 { 00097 void* buffer; 00098 00099 // Copy first buffer 00100 #if defined (__SSE__) && !defined (__sun__) 00101 jack_nframes_t frames_group = nframes / 4; 00102 jack_nframes_t remaining_frames = nframes % 4; 00103 00104 float * source = static_cast<float*>(src_buffers[0]); 00105 float * target = static_cast<float*>(mixbuffer); 00106 00107 while (frames_group > 0) 00108 { 00109 __m128 vec = _mm_load_ps(source); 00110 _mm_store_ps(target, vec); 00111 source += 4; 00112 target += 4; 00113 --frames_group; 00114 } 00115 00116 for (jack_nframes_t i = 0; i != remaining_frames; ++i) 00117 target[i] = source[i]; 00118 00119 #else 00120 memcpy(mixbuffer, src_buffers[0], nframes * sizeof(float)); 00121 #endif 00122 00123 // Mix remaining buffers 00124 for (int i = 1; i < src_count; ++i) { 00125 buffer = src_buffers[i]; 00126 MixAudioBuffer(static_cast<float*>(mixbuffer), static_cast<float*>(buffer), nframes); 00127 } 00128 } 00129 00130 const JackPortType gAudioPortType = 00131 { 00132 JACK_DEFAULT_AUDIO_TYPE, 00133 AudioBufferInit, 00134 AudioBufferMixdown 00135 }; 00136 00137 } // namespace Jack 00138