Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Basic effect generator  (Read 4348 times)

0 Members and 1 Guest are viewing this topic.

Rock_Hardbuns

  • Newbie
  • *
  • Posts: 10
    • View Profile
Basic effect generator
« on: October 29, 2010, 08:03:10 pm »
I made a rudimentary effect synthesizer and sound manager. It's convenient for arcade type games and such. The sound is deliberately a bit distorted, for a little retro vibe.

main.cpp
Code: [Select]

#include <SFML/System.hpp>

#include "soundMan.hpp"



int main(int argc, char** argv)
{

SoundMan* sm = new SoundMan();
int boom = sm->createNoise( 80000, 0.4f, 0.1f, true);
int bam = sm->createNoise( 15000, 1.0f, 1.0f, true);
int zap = sm->createNoise( 5000, 0.0f, 1.0f, false);

int pew = sm->createBeep( 5000, 2000.0f, 50.0f, 0.0f, 0.0f, true);
int alien1 = sm->createBeep( 100000, 2000.0f, 50.0f, 0.5f, 0.9f, true);
int alien2 = sm->createBeep( 100000, 20.0f, 1500.0f, 1.0f, 1.0f, true);
int bigFail = sm->createBeep( 100000, 500.0f, 50.0f, 0.1f, 0.4f, true);

sm->playSound(boom);
sf::Sleep(0.5f);
sm->playSound(bam);
sf::Sleep(0.5f);
sm->playSound(zap);

sf::Sleep(0.5f);
sm->playSound(pew);
sf::Sleep(0.5f);
sm->playSound(alien1);
sf::Sleep(0.5f);
sm->playSound(alien2);
sf::Sleep(0.5f);
sm->playSound(bigFail);
return 0;
}


soundMan.hpp
Code: [Select]

#pragma once
#include <vector>
#include <cmath>
#include <cstdio>
#include <SFML/Audio.hpp>

class SoundMan
{
private:
std::vector<sf::Sound*> playerVec;
std::vector<sf::SoundBuffer*> soundBufVec;

unsigned int currentPlayer;

inline float symClip(float Value, float Limit = 1.0f)
{
return ((fabsf(Value+Limit) - fabsf(Value-Limit)) * 0.5f);
}

public:
SoundMan();
~SoundMan();

void playSound(int index);

//assumes SR = 44100
//Frequencies given in Hz, for example start at 1000.0, end at 100
//Wobble is pitch modulation. Both depth and rate are in the 0.0 to 1.0 range
//A wobble depth of 0.0f turns it off.
int createBeep( int lengthInSamples, float startFrequency, float endFrequency,
float wobbleRate, float wobbleDepth, bool fadeOut);

//Lowpass parameters are in the 0.0 to 1.0 range. 1.0 means the filter is fully open.
int createNoise( int lengthInSamples, float lowPassStart, float lowPassEnd, bool fadeOut);

};


soundMan.cpp
Code: [Select]

#include "soundMan.hpp"


SoundMan::SoundMan()
{
playerVec.push_back( new sf::Sound() );
playerVec.push_back( new sf::Sound() );
playerVec.push_back( new sf::Sound() );
playerVec.push_back( new sf::Sound() );
playerVec.push_back( new sf::Sound() );
currentPlayer = 0;
}



SoundMan::~SoundMan()
{
while(!playerVec.empty())
{
delete playerVec.back();
playerVec.pop_back();
}

while(!soundBufVec.empty())
{
delete soundBufVec.back();
soundBufVec.pop_back();
}
playerVec.clear();
soundBufVec.clear();
}



void SoundMan::playSound(int index)
{
playerVec[currentPlayer]->Stop();
playerVec[currentPlayer]->SetBuffer( *(soundBufVec[index]) );
playerVec[currentPlayer]->Play();

currentPlayer++;
if(currentPlayer == playerVec.size()) currentPlayer = 0;
}



int SoundMan::createBeep( int lengthInSamples, float startFrequency, float endFrequency, float wobbleRate, float wobbleDepth, bool fadeOut)
{
sf::Int16 preBuffer[lengthInSamples];

const float p1 = startFrequency / 44100.0f;
const float p2 = endFrequency / 44100.0f;
float phase = 0.0f;

float wobPhase = 0.0f;

for(int i = 0; i < lengthInSamples; i++)
{
const float alpha = (float)i / (float)lengthInSamples;
const float p = p1 + alpha * (p2 - p1);
phase +=p;
if(phase > 1.0f) phase -= 1.0f;

wobPhase += (wobbleRate * 0.001f);
if(wobPhase > 1.0f) wobPhase -= 1.0f;
const float wob = sin( 2.0 * M_PI * wobPhase);

float tmp = sin( 2.0 * M_PI * (phase + wob * wobbleDepth));

tmp=tmp*tmp*tmp;
tmp = symClip(tmp, 0.6f);

if(fadeOut)
{
const float vol = 1.0f + alpha * -1.0f;
tmp = tmp * vol * vol;
}

preBuffer[i] = sf::Int16(tmp * 32767);
}

sf::SoundBuffer* sBuf = new sf::SoundBuffer();
sBuf->LoadFromSamples(preBuffer, lengthInSamples, 1, 44100);
soundBufVec.push_back(sBuf);
return soundBufVec.size() - 1;
}



int SoundMan::createNoise( int lengthInSamples, float lowPassStart, float lowPassEnd, bool fadeOut)
{
float buf1 = 0.0f;
float buf2 = 0.0f;

const float F1 = lowPassStart * 0.7f;
const float F2 = lowPassEnd * 0.7f;

sf::Int16 preBuffer[lengthInSamples];

for(int i = 0; i < lengthInSamples; i++)
{
float tmp = sf::Randomizer::Random(-0.9f, 0.9f);
const float alpha = (float)i / (float)lengthInSamples;
float F = F1 + alpha * (F2 - F1);
F = F * F * F;

buf1 += F * (tmp - buf1);
buf2 += F * (buf1 - buf2);

tmp = buf2;
tmp = tmp * (1.0f / F);
tmp = symClip(tmp, 0.6f);
if(fadeOut)
{
const float vol = 1.0f + alpha * -1.0f;
tmp = tmp * vol * vol;
}

preBuffer[i] = tmp * 32767;
}


sf::SoundBuffer* sBuf = new sf::SoundBuffer();
sBuf->LoadFromSamples(preBuffer, lengthInSamples, 1, 44100);
soundBufVec.push_back(sBuf);
return soundBufVec.size() - 1;
}



Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
Basic effect generator
« Reply #1 on: October 29, 2010, 09:58:49 pm »
Nice! You should put it on the wiki, too. What's the license on it, btw?

Rock_Hardbuns

  • Newbie
  • *
  • Posts: 10
    • View Profile
Basic effect generator
« Reply #2 on: October 29, 2010, 10:24:43 pm »
Quote from: "Svenstaro"
Nice! You should put it on the wiki, too. What's the license on it, btw?


Public domain.

I haven't tried to figure the wiki out yet, but if someone else want to post it, that's fine with me.