|
Blender
V2.59
|
00001 /* 00002 * $Id: AUD_BandPassReader.cpp 35141 2011-02-25 10:21:56Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * Copyright 2009-2011 Jörg Hermann Müller 00007 * 00008 * This file is part of AudaSpace. 00009 * 00010 * Audaspace is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * AudaSpace is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with Audaspace; if not, write to the Free Software Foundation, 00022 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include "AUD_BandPassReader.h" 00033 #include "AUD_Buffer.h" 00034 00035 #include <cstring> 00036 #include <stdio.h> 00037 00038 AUD_BandPassReader::AUD_BandPassReader(AUD_IReader* reader, float low, 00039 float high) : 00040 AUD_EffectReader(reader), m_low(low), m_high(high) 00041 { 00042 m_buffer = new AUD_Buffer(); AUD_NEW("buffer") 00043 m_in = new AUD_Buffer(); AUD_NEW("buffer") 00044 m_out = new AUD_Buffer(); AUD_NEW("buffer") 00045 m_length = 0; 00046 } 00047 00048 AUD_BandPassReader::~AUD_BandPassReader() 00049 { 00050 if(m_length != 0) 00051 { 00052 fftw_destroy_plan(m_forward); 00053 fftw_destroy_plan(m_backward); 00054 } 00055 00056 delete m_buffer; AUD_DELETE("buffer") 00057 delete m_in; AUD_DELETE("buffer") 00058 delete m_out; AUD_DELETE("buffer") 00059 } 00060 00061 AUD_ReaderType AUD_BandPassReader::getType() 00062 { 00063 return m_reader->getType(); 00064 } 00065 00066 void AUD_BandPassReader::read(int & length, sample_t* & buffer) 00067 { 00068 AUD_Specs specs = m_reader->getSpecs(); 00069 00070 m_reader->read(length, buffer); 00071 00072 if(length > 0) 00073 { 00074 if(length * AUD_SAMPLE_SIZE(specs) > m_buffer->getSize()) 00075 m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); 00076 00077 if(length != m_length) 00078 { 00079 if(m_length != 0) 00080 { 00081 fftw_destroy_plan(m_forward); 00082 fftw_destroy_plan(m_backward); 00083 } 00084 00085 m_length = length; 00086 00087 if(m_length * sizeof(double) > m_in->getSize()) 00088 { 00089 m_in->resize(m_length * sizeof(double)); 00090 m_out->resize((m_length / 2 + 1) * sizeof(fftw_complex)); 00091 } 00092 00093 m_forward = fftw_plan_dft_r2c_1d(m_length, 00094 (double*)m_in->getBuffer(), 00095 (fftw_complex*)m_out->getBuffer(), 00096 FFTW_ESTIMATE); 00097 m_backward = fftw_plan_dft_c2r_1d(m_length, 00098 (fftw_complex*)m_out->getBuffer(), 00099 (double*)m_in->getBuffer(), 00100 FFTW_ESTIMATE); 00101 } 00102 00103 double* target = (double*) m_in->getBuffer(); 00104 sample_t* target2 = m_buffer->getBuffer(); 00105 fftw_complex* complex = (fftw_complex*) m_out->getBuffer(); 00106 float frequency; 00107 00108 for(int channel = 0; channel < specs.channels; channel++) 00109 { 00110 for(int i = 0; i < m_length; i++) 00111 target[i] = buffer[i * specs.channels + channel]; 00112 00113 fftw_execute(m_forward); 00114 00115 for(int i = 0; i < m_length / 2 + 1; i++) 00116 { 00117 frequency = i * specs.rate / (m_length / 2.0f + 1.0f); 00118 if((frequency < m_low) || (frequency > m_high)) 00119 complex[i][0] = complex[i][1] = 0.0; 00120 } 00121 00122 fftw_execute(m_backward); 00123 00124 for(int i = 0; i < m_length; i++) 00125 target2[i * specs.channels + channel] = target[i] / m_length; 00126 } 00127 } 00128 00129 buffer = m_buffer->getBuffer(); 00130 }