// Common, group Output
// Copyright Alexander Liss

#ifndef __SOUND_H__
#define __SOUND_H__

#include "array.h"
#include "shape.h"


namespace Output
{
const float period_unit=(float)1.0e-6;	// of a second
const float std_period=100;				// 10 Khz
const float std_vigor=1;
const float max_period=1.0e6;			// 1 Hz
const float min_period=10;				// 100KHz
}


	// SoundSamples
	// standard vigor
	// samples for a duration "carrier"
	// if sound is periodic, then "carrier"="period"

struct SoundSamples
{
	SimpleArray<unsigned int> samples;
	float period, carrier;

SoundSamples():period(Output::max_period),carrier(Output::max_period){}

int rate(){return (int)(samples.size()/(carrier*Output::period_unit));}
int set_period(float new_period);
int set_rate(int new_rate);
int set_zero();

};

	// SoundAccordUnit

struct SoundAccordUnit
{
	SoundSamples samples;
	VibroData vibro;
	float vigor;

SoundAccordUnit():vigor(Output::std_vigor){}
};

	// SoundAccord

typedef SimpleArray<SoundAccordUnit> SoundAccord;


	// SoundMixer

class SoundMixer
{
SoundMixer(const SoundMixer&);
SoundMixer& operator=(const SoundMixer&);
public:

void reset(){mix.set_zero();}
int add(const SoundSamples& z,float vigor);
int add(const SoundAccord& z);
int get(SoundSamples& z){ z=mix; return 0;} 

private:
	SoundSamples mix;
};


	// Cosin Sound

struct CosinSound
{
	float vigor,period,phase;
	VibroData vibro;

int get(SoundSamples& r); // without vibro, standard vigor
};


struct CosinSoundAccordUnit
{
	int n,m;
	VibroData vibro;
	float vigor;
};


struct CosinSoundAccord
{
	SimpleArray<CosinSoundAccordUnit> units;
	float period,phase;

int get(SoundSamples& r); // without vibro, standard vigor
};

	// FUNCTIONS

int cosin_sound(SoundSamples& r,float amplitude,float period,float phase,int rate);

#endif