Jack2 1.9.7
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     // 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 

Generated for Jack2 by doxygen 1.7.4