Jack2  1.9.10
JackAudioPort.cpp
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