Blender V2.61 - r43446

AUD_BandPassReader.cpp

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