185 lines
6.1 KiB
C++
185 lines
6.1 KiB
C++
#ifndef _SOUND_HPP_
|
|
#define _SOUND_HPP_
|
|
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
|
|
namespace sound {
|
|
|
|
// type of sound.
|
|
// the envelope settings modify each sound.
|
|
enum Sound {
|
|
SoundFrequency=0, // one frequency
|
|
SoundWhiteNoise=1, // all frequencies are equal
|
|
SoundBrownianNoise=2, // 1/f^2 noise
|
|
SoundPinkNoise=3, // 1/f noise
|
|
};
|
|
|
|
enum EnvelopeState {
|
|
New=0, // newly spawned
|
|
Wait, // ready but not yet started (waiting before starting or before repeating)
|
|
Rise, // increasing
|
|
BeginOvershoot,
|
|
EndOvershoot,
|
|
Hold, // staying at normal level
|
|
Decay, // deacying
|
|
Done, // done
|
|
};
|
|
|
|
enum SoundDecayType {
|
|
SoundDecayLinear = 0,
|
|
SoundDecayExp = 1
|
|
};
|
|
|
|
typedef struct {
|
|
// just for debugging/logging. don't rely on use
|
|
const char *name;
|
|
|
|
// unique ID for accessing them via lookups etc. if sound is dead, this will be never reused
|
|
int uid;
|
|
|
|
// if true, don't deallocate once this is done.
|
|
bool keep_when_done;
|
|
|
|
// these are public and can be changed by the user.
|
|
enum EnvelopeState envelope;
|
|
|
|
/****************************************************************/
|
|
/* Special Parameters for specific types */
|
|
/****************************************************************/
|
|
|
|
/******************** SoundFrequency ****************************/
|
|
|
|
float freq; // base frequency for type: SoundFrequency
|
|
|
|
/******************** White / Brownian / Pink Noise ****************/
|
|
float leakage; // influence of previous state on current value (0..1)
|
|
float scaling; // influence of white noise on next value
|
|
|
|
// If true and the value goes outside (-1..1), do the step in the other
|
|
// direction to stay inside the valid range.
|
|
bool skipDirectionIfClamping;
|
|
|
|
/******************** SoundFrequency: ***************************/
|
|
|
|
/****************************************************************/
|
|
/* Common sound state / parameters */
|
|
/****************************************************************/
|
|
// progress of the sound which is used for the envelope but can be used for
|
|
// other things too
|
|
float time;
|
|
|
|
// scalar state that can be used arbitrarily to derive the waveform from it
|
|
float state;
|
|
|
|
// time when the sound is done
|
|
// if != 0.0, the sound changes with that
|
|
// TODO: make attack gain decay stuff as envelope
|
|
// TODO: add amplitude noise
|
|
float _riseTime;
|
|
float _relativeOvershootTime; // percentage of end of rise time that is used for overshoot (max amplitude at t_overshoot/2)
|
|
float _holdTime;
|
|
float _decayTime;
|
|
float _waitTime;
|
|
|
|
// waveform of type of rise. default: linear
|
|
enum SoundDecayType riseType;
|
|
|
|
// waveform of type of decay. default: linear
|
|
enum SoundDecayType decayType;
|
|
|
|
// if true, play infinitely
|
|
bool looping;
|
|
|
|
// base amplitude of the sound
|
|
float amplitude;
|
|
|
|
// amplitude when signal is at minimum (before rise, after release and in wait time)
|
|
float minAmplitude;
|
|
|
|
// these are al private!
|
|
// never acces them
|
|
enum Sound _type; // which type of sound
|
|
|
|
int _loopCount;
|
|
|
|
// if true, will get removed
|
|
bool _done;
|
|
bool _useEnvelope;
|
|
|
|
float *history; // if != 0, history is a pointer to 2*numHistorySamples samples.
|
|
size_t numHistorySamples; // if != 0, save history for this sound.
|
|
size_t lastHistorySample; // index/2 of last history sample. used
|
|
} SoundHandle;
|
|
|
|
// initialize sound subsystem. return true if working, false on errors.
|
|
bool initSound(void);
|
|
|
|
// start playing a sound.
|
|
// args:
|
|
// type - type of sound.
|
|
// amplitude : 0..1
|
|
// handle: if != NULL will point to the internal sound handle to change the
|
|
// manipulate playing of the sound.
|
|
// TODO: add sound from file to play too
|
|
SoundHandle *playSound(enum Sound type, float amplitude);
|
|
|
|
// start playing a looping frequency.
|
|
// args:
|
|
// freq: frequency in Hz
|
|
SoundHandle *playFrequency(float freq, float amplitude);
|
|
|
|
// set them.
|
|
// args:
|
|
// time of phases
|
|
bool configureEnvelope(SoundHandle *handle, float rise, float hold, float decay);
|
|
|
|
bool configureOvershoot(SoundHandle *handle, float relativeOvershootTime);
|
|
|
|
// same as above but set to looping and set wait time between intervals
|
|
bool configureEnvelopeWait(SoundHandle *handle, float rise, float hold, float decay, float wait);
|
|
|
|
// without looping but with wait
|
|
bool configureEnvelopeLooping(SoundHandle *handle, float rise, float hold, float decay, float wait);
|
|
|
|
// getter for attributes. if 0.0, unused.
|
|
float getRiseDuration(SoundHandle *handle);
|
|
float getHoldDuration(SoundHandle *handle);
|
|
float getDecayDuration(SoundHandle *handle);
|
|
|
|
float getWaitTime(SoundHandle *handle);
|
|
void configureWaitTime(SoundHandle *handle, float waitTime);
|
|
|
|
// Set looping behaviour of the sound.
|
|
// args:
|
|
// / > 0, sound is looping for this number of repetitions
|
|
// numRepetitions { == 0, sound is stopped when it is over
|
|
// \ == -1, loop the sound forever
|
|
//
|
|
void setLoopCount(SoundHandle *handle, int numRepetitions);
|
|
|
|
// stop playing a sound. the handle is invalid now.
|
|
bool stopSound(SoundHandle *handle);
|
|
|
|
// stop and remove all playing sounds. all handle become invalid after calling
|
|
// this.
|
|
void stopAllSounds(void);
|
|
|
|
void teardownSound(void);
|
|
|
|
// for debugging
|
|
bool startDumpingWav(const char *filename);
|
|
|
|
// is deletede when 'keep' not set after stopping
|
|
void stopDumpingWav(void);
|
|
|
|
int numActiveSounds(void);
|
|
|
|
void deleteSound(SoundHandle *handle);
|
|
|
|
//SoundHandle *playFreqEnvelope(float freq, float rise, float hold, float decay);
|
|
|
|
// TODO: add fade out/fade in overlay stuff for stopping sounds smoothly
|
|
}
|
|
|
|
#endif
|