Jack2
1.9.7
|
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 "JackGlobals.h" 00022 #include "JackEngineControl.h" 00023 #include "JackPortType.h" 00024 00025 #include <string.h> 00026 00027 #if defined (__APPLE__) 00028 #include <Accelerate/Accelerate.h> 00029 #elif defined (__SSE__) && !defined (__sun__) 00030 #include <xmmintrin.h> 00031 #endif 00032 00033 namespace Jack 00034 { 00035 00036 static void AudioBufferInit(void* buffer, size_t buffer_size, jack_nframes_t) 00037 { 00038 memset(buffer, 0, buffer_size); 00039 } 00040 00041 static inline void MixAudioBuffer(jack_default_audio_sample_t* mixbuffer, jack_default_audio_sample_t* buffer, jack_nframes_t frames) 00042 { 00043 #ifdef __APPLE__ 00044 // It seems that a vector mult only operation does not exist... 00045 jack_default_audio_sample_t gain = jack_default_audio_sample_t(1.0); 00046 vDSP_vsma(buffer, 1, &gain, mixbuffer, 1, mixbuffer, 1, frames); 00047 #else 00048 jack_nframes_t frames_group = frames / 4; 00049 frames = frames % 4; 00050 00051 while (frames_group > 0) { 00052 #if defined (__SSE__) && !defined (__sun__) 00053 __m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer)); 00054 _mm_store_ps(mixbuffer, vec); 00055 00056 mixbuffer += 4; 00057 buffer += 4; 00058 frames_group--; 00059 #else 00060 register jack_default_audio_sample_t mixFloat1 = *mixbuffer; 00061 register jack_default_audio_sample_t sourceFloat1 = *buffer; 00062 register jack_default_audio_sample_t mixFloat2 = *(mixbuffer + 1); 00063 register jack_default_audio_sample_t sourceFloat2 = *(buffer + 1); 00064 register jack_default_audio_sample_t mixFloat3 = *(mixbuffer + 2); 00065 register jack_default_audio_sample_t sourceFloat3 = *(buffer + 2); 00066 register jack_default_audio_sample_t mixFloat4 = *(mixbuffer + 3); 00067 register jack_default_audio_sample_t sourceFloat4 = *(buffer + 3); 00068 00069 buffer += 4; 00070 frames_group--; 00071 00072 mixFloat1 += sourceFloat1; 00073 mixFloat2 += sourceFloat2; 00074 mixFloat3 += sourceFloat3; 00075 mixFloat4 += sourceFloat4; 00076 00077 *mixbuffer = mixFloat1; 00078 *(mixbuffer + 1) = mixFloat2; 00079 *(mixbuffer + 2) = mixFloat3; 00080 *(mixbuffer + 3) = mixFloat4; 00081 00082 mixbuffer += 4; 00083 #endif 00084 } 00085 00086 while (frames > 0) { 00087 register jack_default_audio_sample_t mixFloat1 = *mixbuffer; 00088 register jack_default_audio_sample_t sourceFloat1 = *buffer; 00089 buffer++; 00090 frames--; 00091 mixFloat1 += sourceFloat1; 00092 *mixbuffer = mixFloat1; 00093 mixbuffer++; 00094 } 00095 #endif 00096 } 00097 00098 static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) 00099 { 00100 void* buffer; 00101 00102 // Copy first buffer 00103 #if defined (__SSE__) && !defined (__sun__) 00104 jack_nframes_t frames_group = nframes / 4; 00105 jack_nframes_t remaining_frames = nframes % 4; 00106 00107 jack_default_audio_sample_t * source = static_cast<jack_default_audio_sample_t*>(src_buffers[0]); 00108 jack_default_audio_sample_t * target = static_cast<jack_default_audio_sample_t*>(mixbuffer); 00109 00110 while (frames_group > 0) 00111 { 00112 __m128 vec = _mm_load_ps(source); 00113 _mm_store_ps(target, vec); 00114 source += 4; 00115 target += 4; 00116 --frames_group; 00117 } 00118 00119 for (jack_nframes_t i = 0; i != remaining_frames; ++i) 00120 target[i] = source[i]; 00121 00122 #else 00123 memcpy(mixbuffer, src_buffers[0], nframes * sizeof(jack_default_audio_sample_t)); 00124 #endif 00125 00126 // Mix remaining buffers 00127 for (int i = 1; i < src_count; ++i) { 00128 buffer = src_buffers[i]; 00129 MixAudioBuffer(static_cast<jack_default_audio_sample_t*>(mixbuffer), static_cast<jack_default_audio_sample_t*>(buffer), nframes); 00130 } 00131 } 00132 00133 static size_t AudioBufferSize() 00134 { 00135 return GetEngineControl()->fBufferSize * sizeof(jack_default_audio_sample_t); 00136 } 00137 00138 const JackPortType gAudioPortType = 00139 { 00140 JACK_DEFAULT_AUDIO_TYPE, 00141 AudioBufferSize, 00142 AudioBufferInit, 00143 AudioBufferMixdown 00144 }; 00145 00146 } // namespace Jack 00147