Jack2 1.9.10
|
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 vDSP_vadd(buffer, 1, mixbuffer, 1, mixbuffer, 1, frames); 00045 #else 00046 jack_nframes_t frames_group = frames / 4; 00047 frames = frames % 4; 00048 00049 while (frames_group > 0) { 00050 #if defined (__SSE__) && !defined (__sun__) 00051 __m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer)); 00052 _mm_store_ps(mixbuffer, vec); 00053 00054 mixbuffer += 4; 00055 buffer += 4; 00056 frames_group--; 00057 #else 00058 register jack_default_audio_sample_t mixFloat1 = *mixbuffer; 00059 register jack_default_audio_sample_t sourceFloat1 = *buffer; 00060 register jack_default_audio_sample_t mixFloat2 = *(mixbuffer + 1); 00061 register jack_default_audio_sample_t sourceFloat2 = *(buffer + 1); 00062 register jack_default_audio_sample_t mixFloat3 = *(mixbuffer + 2); 00063 register jack_default_audio_sample_t sourceFloat3 = *(buffer + 2); 00064 register jack_default_audio_sample_t mixFloat4 = *(mixbuffer + 3); 00065 register jack_default_audio_sample_t sourceFloat4 = *(buffer + 3); 00066 00067 buffer += 4; 00068 frames_group--; 00069 00070 mixFloat1 += sourceFloat1; 00071 mixFloat2 += sourceFloat2; 00072 mixFloat3 += sourceFloat3; 00073 mixFloat4 += sourceFloat4; 00074 00075 *mixbuffer = mixFloat1; 00076 *(mixbuffer + 1) = mixFloat2; 00077 *(mixbuffer + 2) = mixFloat3; 00078 *(mixbuffer + 3) = mixFloat4; 00079 00080 mixbuffer += 4; 00081 #endif 00082 } 00083 00084 while (frames > 0) { 00085 register jack_default_audio_sample_t mixFloat1 = *mixbuffer; 00086 register jack_default_audio_sample_t sourceFloat1 = *buffer; 00087 buffer++; 00088 frames--; 00089 mixFloat1 += sourceFloat1; 00090 *mixbuffer = mixFloat1; 00091 mixbuffer++; 00092 } 00093 #endif 00094 } 00095 00096 static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) 00097 { 00098 void* buffer; 00099 00100 // Copy first buffer 00101 #if defined (__SSE__) && !defined (__sun__) 00102 jack_nframes_t frames_group = nframes / 4; 00103 jack_nframes_t remaining_frames = nframes % 4; 00104 00105 jack_default_audio_sample_t* source = static_cast<jack_default_audio_sample_t*>(src_buffers[0]); 00106 jack_default_audio_sample_t* target = static_cast<jack_default_audio_sample_t*>(mixbuffer); 00107 00108 while (frames_group > 0) { 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 00120 #else 00121 memcpy(mixbuffer, src_buffers[0], nframes * sizeof(jack_default_audio_sample_t)); 00122 #endif 00123 00124 // Mix remaining buffers 00125 for (int i = 1; i < src_count; ++i) { 00126 buffer = src_buffers[i]; 00127 MixAudioBuffer(static_cast<jack_default_audio_sample_t*>(mixbuffer), static_cast<jack_default_audio_sample_t*>(buffer), nframes); 00128 } 00129 } 00130 00131 static size_t AudioBufferSize() 00132 { 00133 return GetEngineControl()->fBufferSize * sizeof(jack_default_audio_sample_t); 00134 } 00135 00136 const JackPortType gAudioPortType = 00137 { 00138 JACK_DEFAULT_AUDIO_TYPE, 00139 AudioBufferSize, 00140 AudioBufferInit, 00141 AudioBufferMixdown 00142 }; 00143 00144 } // namespace Jack 00145