Jack2 1.9.6

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 "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