Blender  V2.59
AUD_BandPassReader.cpp
Go to the documentation of this file.
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 }