KlassischeKeplerKriege/game/sound/sound.hpp
2016-10-03 18:45:24 +02:00

196 lines
6.5 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
};
struct SoundHandle {
// 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
size_t uid;
// marked for deletion by the internal thread.
bool deleteFlag;
// is now deleted. when a new sound should be used, this can be reused
// and at the end deleteFlag and isDeleted should be cleared.
bool isDeleted;
// 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
};
// initialize sound subsystem. return true if working, false on errors.
bool initSound(void);
// free sounds that are not used anymore.
// must be called regularily by the application
void deleteOldSounds();
// 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