Sound processing

<< return to C++ examples

Overview

The ALSoundProcessing example module shows how to process sound data and interact with ALMemory. It writes the RMS power of all four channels in ALMemory.

This is a remote or local module.

Downloads

Whole module

soundprocessing.zip

Header: alsoundprocessing.h

alsoundprocessing.h

/**
* @author Gwennael Gate
* Copyright (c) Aldebaran Robotics 2010, 2011
*/


#ifndef SOUNDPROCESSING_H
#define SOUNDPROCESSING_H
#include <string>
#include <rttools/rttime.h>

#ifdef SOUNDPROCESSING_IS_REMOTE
#include <qi/application.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#endif

#include <boost/shared_ptr.hpp>
#include <alvalue/alvalue.h>
#include <alproxies/almemoryproxy.h>
#include <alaudio/alsoundextractor.h>

using namespace AL;

class ALSoundProcessing : public ALSoundExtractor
{

public:

  ALSoundProcessing(boost::shared_ptr<ALBroker> pBroker, std::string pName);
  virtual ~ALSoundProcessing();

  //method inherited from almodule that will be called after constructor
  void init();

public:
  void process(const int & nbOfChannels,
               const int & nbrOfSamplesByChannel,
               const AL_SOUND_FORMAT * buffer,
               const ALValue & timeStamp);

private:
  ALMemoryProxy fProxyToALMemory;
  std::vector<std::string> fALMemoryKeys;
};
#endif

Source: alsoundprocessing.cpp

alsoundprocessing.cpp

#include "alsoundprocessing.h"
#include <alcommon/alproxy.h>
#include <iostream>

ALSoundProcessing::ALSoundProcessing(boost::shared_ptr<ALBroker> pBroker,
                                     std::string pName)
  : ALSoundExtractor(pBroker, pName)
{
  setModuleDescription("This module processes the data collected by the "
                       "microphones and output in the ALMemory the RMS power "
                       "of each of the four channels.");

}

void ALSoundProcessing::init()
{
  fALMemoryKeys.push_back("ALSoundProcessing/leftMicEnergy");
  fALMemoryKeys.push_back("ALSoundProcessing/rightMicEnergy");
  fALMemoryKeys.push_back("ALSoundProcessing/frontMicEnergy");
  fALMemoryKeys.push_back("ALSoundProcessing/rearMicEnergy");

  fProxyToALMemory.insertData(fALMemoryKeys[0],0.0f);
  fProxyToALMemory.insertData(fALMemoryKeys[1],0.0f);
  fProxyToALMemory.insertData(fALMemoryKeys[2],0.0f);
  fProxyToALMemory.insertData(fALMemoryKeys[3],0.0f);


  // Do not call the function setClientPreferences in your constructor!
  // setClientPreferences : can be called after its construction!
  audioDevice->callVoid("setClientPreferences",
                        getName(),                //Name of this module
                        48000,                    //48000 Hz requested
                        (int)ALLCHANNELS,         //4 Channels requested
                        1                         //Deinterleaving requested
                        );
#ifdef SOUNDPROCESSING_IS_REMOTE
  qi::Application::atStop(boost::bind(&ALSoundProcessing::stopDetection, this));
#endif
  startDetection();
}

ALSoundProcessing::~ALSoundProcessing()
{
  stopDetection();
}


/// Description: The name of this method should not be modified as this
/// method is automatically called by the AudioDevice Module.
void ALSoundProcessing::process(const int & nbOfChannels,
                                const int & nbOfSamplesByChannel,
                                const AL_SOUND_FORMAT * buffer,
                                const ALValue & timeStamp)
{
  /// Computation of the RMS power of the signal delivered by
  /// each microphone on a 170ms buffer
  /// init RMS power to 0
  std::vector<float> fMicsEnergy;
  for(int i=0 ; i<nbOfChannels ; i++)
  {
    fMicsEnergy.push_back(0.0f);
  }

  /// Calculation of the RMS power
  for(int channelInd = 0 ; channelInd < nbOfChannels ; channelInd++)
  {
    for(int i = 0 ; i < nbOfSamplesByChannel ; i++)
    {
      fMicsEnergy[channelInd] += (float)buffer[nbOfSamplesByChannel*channelInd + i]
                                 *(float)buffer[nbOfSamplesByChannel*channelInd + i];
    }
    fMicsEnergy[channelInd] /= (float)nbOfSamplesByChannel;
    fMicsEnergy[channelInd] = sqrtf(fMicsEnergy[channelInd]);
  }

  /// Puts the result in ALMemory
  /// (for example to be easily retrieved by another module)
  for(int i=0 ; i<nbOfChannels ; i++)
  {
    fProxyToALMemory.insertData(fALMemoryKeys[i],fMicsEnergy[i]);
  }

  /// Displays the results on the Naoqi console
  std::cout << "ALSoundProcessing Energy Left  = " <<  fMicsEnergy[0] << std::endl;
  std::cout << "ALSoundProcessing Energy Right  = " << fMicsEnergy[1] << std::endl;
  std::cout << "ALSoundProcessing Energy Front  = " << fMicsEnergy[2] << std::endl;
  std::cout << "ALSoundProcessing Energy Rear  = " <<  fMicsEnergy[3] << std::endl;
}

Main: main.cpp

soundprocessingmain.cpp

/// <summary>
/// This file has been generated automatically through the module generator provided in the sdk.
///  This file handle the creation of the dynamic library (local use) or the executable (remote use).
/// </summary>
/// <remarks> Copyright 2010 A. Dupont </remarks>


#include <signal.h>
#include <boost/shared_ptr.hpp>
#include <alcommon/albroker.h>
#include <alcommon/almodule.h>
#include <alcommon/albrokermanager.h>
#include <alcommon/altoolsmain.h>

// include the modules
#include "alsoundprocessing.h"

#ifdef SOUNDPROCESSING_IS_REMOTE
# define ALCALL
#else
# ifdef _WIN32
#  define ALCALL __declspec(dllexport)
# else
#  define ALCALL
# endif
#endif

extern "C"
{

  ALCALL int _createModule(boost::shared_ptr<AL::ALBroker> pBroker)
  {
    // init broker with the main broker instance
    // from the parent executable
    AL::ALBrokerManager::setInstance(pBroker->fBrokerManager.lock());
    AL::ALBrokerManager::getInstance()->addBroker(pBroker);

    // create module instances
    AL::ALModule::createModule<ALSoundProcessing>(pBroker,"ALSoundProcessing");
    return 0;
  }

  ALCALL int _closeModule()
  {
    return 0;
  }

} // extern "C"


#ifdef SOUNDPROCESSING_IS_REMOTE

int main(int argc, char *argv[] )
{
  // pointer to createModule
  TMainType sig;
  sig = &_createModule;

  // call main
  ALTools::mainFunction("alsoundprocessing", argc, argv, sig);
}

#endif

CMakeLists.txt

CMakeLists.txt

# Copyright (C) 2010 Aldebaran Robotics

cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
project(soundprocessing)
find_package(qibuild)

option(SOUNDPROCESSING_IS_REMOTE
  "module is compiled as a remote module (ON or OFF)"
  ON)

set(_srcs
    main.cpp
    alsoundprocessing.h
    alsoundprocessing.cpp
)

if(SOUNDPROCESSING_IS_REMOTE)
  add_definitions(" -DSOUNDPROCESSING_IS_REMOTE ")
  qi_create_bin(soundprocessing ${_srcs})
else()
  qi_create_lib(soundprocessing SHARED ${_srcs} SUBFOLDER naoqi)
endif()


qi_use_lib(soundprocessing ALCOMMON ALPROXIES ALAUDIO)