beatanalyser.cpp
Go to the documentation of this file.
00001 /****************************************************************
00002  *
00003  * Copyright (c) 2010
00004  *
00005  * Fraunhofer Institute for Manufacturing Engineering   
00006  * and Automation (IPA)
00007  *
00008  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00009  *
00010  * Project name: care-o-bot
00011  * ROS stack name: cob_driver
00012  * ROS package name: cob_light
00013  * Description: Switch robots led color by sending data to
00014  * the led-µC over serial connection.
00015  *                              
00016  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00017  *          
00018  * Author: Benjamin Maidel, email:benjamin.maidel@ipa.fraunhofer.de
00019  * Supervised by: Benjamin Maidel, email:benjamin.maidel@ipa.fraunhofer.de
00020  *
00021  * Date of creation: August 2012
00022  * ToDo:
00023  *
00024  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00025  *
00026  * Redistribution and use in source and binary forms, with or without
00027  * modification, are permitted provided that the following conditions are met:
00028  *
00029  *     * Redistributions of source code must retain the above copyright
00030  *       notice, this list of conditions and the following disclaimer.
00031  *     * Redistributions in binary form must reproduce the above copyright
00032  *       notice, this list of conditions and the following disclaimer in the
00033  *       documentation and/or other materials provided with the distribution.
00034  *     * Neither the name of the Fraunhofer Institute for Manufacturing 
00035  *       Engineering and Automation (IPA) nor the names of its
00036  *       contributors may be used to endorse or promote products derived from
00037  *       this software without specific prior written permission.
00038  *
00039  * This program is free software: you can redistribute it and/or modify
00040  * it under the terms of the GNU Lesser General Public License LGPL as 
00041  * published by the Free Software Foundation, either version 3 of the 
00042  * License, or (at your option) any later version.
00043  * 
00044  * This program is distributed in the hope that it will be useful,
00045  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00046  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00047  * GNU Lesser General Public License LGPL for more details.
00048  * 
00049  * You should have received a copy of the GNU Lesser General Public 
00050  * License LGPL along with this program. 
00051  * If not, see <http://www.gnu.org/licenses/>.
00052  *
00053  ****************************************************************/
00054  
00055 #include "beatanalyser.h"
00056 namespace mybeat
00057 {
00058 
00059 BeatAnalyser::BeatAnalyser(uint16_t num_bands, uint32_t samplerate, uint16_t recordsize)
00060 : m_maxBandValue(0.0)
00061 {
00062     this->m_bandCount=num_bands;
00063     this->m_sampleRate=samplerate;
00064     this->m_recordSize=recordsize;
00065     m_SubBands = new std::vector<Band*>;
00066     for(uint16_t i=0;i<num_bands;i++)
00067     {
00068         /*Create a new subband with 4 seconds of history and 50% decrease of the allTimeMaximum after 2 seconds*/
00069         Band *tmp = new Band(4*samplerate/recordsize, pow(0.5,(1/((double)samplerate/recordsize))));
00070         m_SubBands->push_back(tmp);
00071     }
00072     //m_beats = new QVector<bool> (num_bands,false);
00073     m_beats = new std::vector<bool> (num_bands,false);
00074 }
00075 BeatAnalyser::~BeatAnalyser()
00076 {
00077     delete m_SubBands;
00078     delete m_beats;
00079 }
00080 void BeatAnalyser::processData()
00081 {
00082     uint16_t freq_per_band=m_recordSize/2/m_bandCount/8;
00083     //m_beats->fill(false);
00084     m_beats->assign(m_bandCount, false);
00085     for(uint16_t i=0;i<m_bandCount;i++)
00086     {
00087         double sum=0;
00088         for(uint16_t j=0;j<freq_per_band;j++)
00089         {
00090             sum+=m_FFT->get_magnitude(i*freq_per_band+j);
00091         }
00092         sum/=freq_per_band;
00093         if(sum > m_maxBandValue)
00094             m_maxBandValue = sum;
00095 
00096         m_SubBands->at(i)->log(sum);
00097         if(m_SubBands->at(i)->average() < sum && m_SubBands->at(i)->getAllTimeMaximum()*0.8 < sum)
00098         {
00099             //m_beats->replace(i,true);
00100             (*m_beats)[i] = true;
00101         }
00102     }
00103 }
00104 double BeatAnalyser::getMagSpectrum(uint32_t low, uint32_t high)
00105 {
00106     static double magSpecMax = 0;
00107     double magSpec=0;
00108     uint16_t freq_per_band= m_sampleRate/m_bandCount;
00109     uint32_t low_limit=low/freq_per_band;
00110     uint32_t high_limit=high/freq_per_band;
00111     double avgAllTimeMax = 0;
00112     double avgAverage = 0;
00113     
00114     for(uint16_t i=low_limit; i<high_limit;i++)
00115     {
00116         avgAllTimeMax+= m_SubBands->at(i)->getAllTimeMaximumRaw();
00117         if(m_SubBands->at(i)->getNewest() > avgAverage)
00118             avgAverage = m_SubBands->at(i)->getNewest();
00119     }
00120     magSpec = avgAverage / (avgAllTimeMax/(high_limit-low_limit));
00121     if(magSpec > magSpecMax)
00122         magSpecMax = magSpec;
00123     else
00124         magSpecMax *= 0.8;
00125     magSpec = magSpec / magSpecMax;
00126     //printf("magSpec: %f\n", magSpec);
00127     return magSpec;
00128 }
00129 
00130 bool BeatAnalyser::getBeat(uint16_t pos)
00131 {
00132     if(pos < m_bandCount)
00133         return m_beats->at(pos);
00134     else
00135         return false;
00136 }
00137 bool BeatAnalyser::getBeatFrequency(uint32_t frequency)
00138 {
00139     uint16_t freq_per_band=m_sampleRate/m_bandCount;
00140     return m_beats->at((int)frequency/freq_per_band);
00141 }
00142 bool BeatAnalyser::getDrumBeat()
00143 {
00144     /*We want to detect beats from 50Hz up to 200Hz*/
00145     bool tmp=false;
00146     uint16_t freq_per_band=m_sampleRate/m_bandCount;
00147     uint32_t low_limit=50/freq_per_band;
00148     uint32_t high_limit=200/freq_per_band;
00149     if(high_limit == 0)
00150        high_limit=1; /*If we have few bands, just take the first one*/
00151 
00152     for(uint16_t i=low_limit;i<high_limit;i++)
00153         tmp |= m_beats->at(i);
00154     return tmp;
00155 }
00156 bool BeatAnalyser::getSnareBeat()
00157 {
00158     /*We want to detect beats from 1500Hz up to 2500Hz - this of course will return a beat more often due to the broad spectrum*/
00159     bool tmp=false;
00160     uint16_t freq_per_band=m_sampleRate/m_bandCount;
00161     uint32_t low_limit=1500/freq_per_band;
00162     uint32_t high_limit=2000/freq_per_band;
00163     for(uint16_t i=low_limit;i<high_limit;i++)
00164         tmp |= m_beats->at(i);
00165     return tmp;
00166 }
00167 Band* BeatAnalyser::getBand(uint16_t pos)
00168 {
00169     if(pos < m_bandCount)
00170         return m_SubBands->at(pos);
00171     else
00172         return NULL;
00173 }
00174 } 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


cob_lightmode
Author(s): Benjamin Maidel
autogenerated on Thu Jan 17 2013 13:39:37