Ejemplo n.º 1
0
LRESULT CMainDlg::OnSave(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	char fileName[MAX_PATH];
	memset(fileName, 0, sizeof(fileName));
	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = m_hWnd;
	ofn.lpstrFilter = "Sound Files(*.wav)\0*.wav\0All Files(*.*)\0*.*\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = fileName;
	ofn.lpstrDefExt = ".wav";
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_OVERWRITEPROMPT;
	
	if (GetSaveFileName (&ofn))
	{
		WaveFile wvf;
		wvf.OpenWaveFile(fileName, 2);
		InitGen();
		long totalSamples = (long) ((durTotal * synthParams.sampleRate) + 0.5);
		long atkSamples = (long) (durAtkSus * synthParams.sampleRate);
		long n;
		for (n = 0; n < atkSamples; n++)
			wvf.Output1(Generate());
		NoteOff();
		while (n++ < totalSamples)
			wvf.Output1(Generate());
		for (n = 0; n < 440; n++)
			wvf.Output1(0);
		wvf.CloseWaveFile();
	}
	return 0;
}
Ejemplo n.º 2
0
LRESULT CMainDlg::OnSaveWave(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	char fileName[MAX_PATH];
	memset(fileName, 0, sizeof(fileName));
	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = m_hWnd;
	ofn.lpstrFilter = "Sound Files(*.wav)\0*.wav\0All Files(*.*)\0*.*\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = fileName;
	ofn.lpstrDefExt = ".wav";
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_OVERWRITEPROMPT;
	
	if (GetSaveFileName (&ofn))
	{
		double frq = GetFrequency();
		GenWaveI wv;
		wv.InitWT(frq, WT_USR(0));
		EnvGen eg;
		eg.InitEG(1.0, 2.0, 0.05, 0.05);
		WaveFile wvf;
		wvf.OpenWaveFile(fileName, 2);
		long totalSamples = (long) (2.0 * synthParams.sampleRate);
		for (long n = 0; n < totalSamples; n++)
			wvf.Output1(eg.Gen() * wv.Gen());
		wvf.CloseWaveFile();

	}
	return 0;
}
Ejemplo n.º 3
0
void GenerateVib(FrqValue duration, GenWave *wv, EnvGen *eg, AmpValue lfoAmp)
{
	GenWave32 lfo;
	lfo.InitWT(3.5, WT_SIN);

	long totalSamples = (long) ((duration * synthParams.sampleRate) + 0.5);
	AmpValue volume;
	AmpValue value;

	eg->Reset();

	for (long n = 0; n < totalSamples; n++)
	{
		volume = eg->Gen();
		wv->Modulate(lfoAmp * lfo.Gen());
		value = wv->Sample(1.0);
		wvf.Output1(value * volume);
	}
}
Ejemplo n.º 4
0
AmpValue Generate(float duration, GenUnit *wv, EnvGen *eg, AmpValue in = 1.0)
{
	long totalSamples = (long) ((duration * synthParams.sampleRate) + 0.5);
	AmpValue volume;
	AmpValue value;
	AmpValue peak = 0.0;

	eg->Reset();

	for (long n = 0; n < totalSamples; n++)
	{
		volume = eg->Gen();
		value = wv->Sample(in);
		if (value > peak)
			peak = value;
		wvf.Output1(value * volume);
	}
	return peak;
}
Ejemplo n.º 5
0
void Silence(FrqValue duration)
{
	long totalSamples = (long) ((duration * synthParams.sampleRate) + 0.5);
	for (long n = 0; n < totalSamples; n++)
		wvf.Output1(0);
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
	InitSynthesizer();

	long n;
	int pitch = 48;
	FrqValue duration = 2.75;
	AmpValue value1, value2;

	if (argc > 1)
		duration = atof(argv[1]);
	if (argc > 2)
		pitch = atoi(argv[2]);

	FrqValue frequency = synthParams.GetFrequency(pitch);

	if (wvf.OpenWaveFile("example07b.wav", 2))
	{
		printf("Cannot open wavefile for output\n");
		exit(1);
	}

	GenWaveFM wv;
	wv.InitFM(frequency, 1, 2, WT_SIN);

	EnvGen eg;
	eg.InitEG(0.5f, duration, 0.5f, 0.5f);

	long totalSamples = (long) ((duration * synthParams.sampleRate) + 0.5);

	// reference sound. 
	for (n = 0; n < totalSamples; n++)
	{
		value2 = (eg.Gen() * wv.Gen());
		wvf.Output1(value2);
	}
	Silence(0.25);


	// Flanger #1 varies from 0 to 5ms
	Flanger flng1;
	flng1.InitFlanger(0.5, 0.5, 0, 0.0025, 0.005, 0.15);

	// Flanger #2 varies from 45 to 50ms
	Flanger flng2;
	flng2.InitFlanger(0.5, 0.5, 0, 0.0042, 0.005, 0.15);

	// Flanger #3 is set for a chorus effect
	Flanger flng3;
	flng3.InitFlanger(0.5, 0.5, 0.5, 0.100, 0.001, 0.8);

	for (float snd = 0.5; snd <= 1; snd += 0.5)
	{
		wv.InitFM(frequency*snd, 1, 2, WT_SIN);
		eg.Reset();
		flng1.Clear();
		for (n = 0; n < totalSamples; n++)
		{
			value1 = (eg.Gen() * wv.Gen());
			value2 = flng1.Sample(value1);
			wvf.Output2(value2, value2);
		}
		Silence(0.25);

		eg.Reset();
		flng2.Clear();
		for (n = 0; n < totalSamples; n++)
		{
			value1 = (eg.Gen() * wv.Gen());
			value2 = flng2.Sample(value1);
			wvf.Output2(value2, value2);
		}
		Silence(0.25);

		eg.Reset();
		flng3.Clear();
		for (n = 0; n < totalSamples; n++)
		{
			value1 = (eg.Gen() * wv.Gen());
			value2 = flng3.Sample(value1);
			wvf.Output2(value2, value2);
		}
		Silence(0.25);
	}

	wvf.CloseWaveFile();

	return 0;
}
Ejemplo n.º 7
0
void Silence(float t)
{
	long n = (long) (t * synthParams.sampleRate);
	while (n-- > 0)
		wvf.Output1(0);
}
Ejemplo n.º 8
0
int main(int argc, char *argv[])
{
	int pitch = 48; // Middle C
	FrqValue duration = 1;
	AmpValue peakAmp = 1;

	if (argc > 1)
		duration = atof(argv[1]);
	if (argc > 2)
		pitch = atoi(argv[2]);
	if (argc > 3)
		peakAmp = atof(argv[3]);

	InitSynthesizer();
	FrqValue frequency = synthParams.GetFrequency(pitch);
	PhsAccum phaseIncr = synthParams.frqRad * frequency;
	PhsAccum phase = 0;

	long silence = (long) (synthParams.sampleRate * 0.1);
	long totalSamples = (long) ((synthParams.sampleRate * duration) + 0.5);

	long attackTime = (long) (0.2 * synthParams.sampleRate);
	long decayTime  = (long) (0.4 * synthParams.sampleRate);
	long sustainTime = totalSamples - (attackTime + decayTime);
	long decayStart = totalSamples - decayTime;
	AmpValue envInc = peakAmp / (float) attackTime;
	AmpValue volume = 0;

	long n;

	WaveFile wf;
	if (wf.OpenWaveFile("example02.wav", 1))
	{
		printf("Cannot open wavefile for output\n");
		exit(1);
	}

	/////////////////////////////////////////////////
	// Method 1 - simple integration, linear
	/////////////////////////////////////////////////
	long sampleNumber = 0;
	for (n = 0; n < totalSamples; n++)
	{
		if (n < attackTime || n > decayStart)
			volume += envInc;
		else if (n == attackTime)
			volume = peakAmp;
		else if (n == decayStart)
			envInc = -volume / (float) decayTime;
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 1 - convex exponential (n^2)
	/////////////////////////////////////////////////
	sampleNumber = 0;
	volume = 0;
	phase = 0;
	envInc = peakAmp / (float) attackTime;
	for (n = 0; n < totalSamples; n++)
	{
		if (n < attackTime || n > decayStart)
			volume += envInc;
		else if (n == attackTime)
			volume = peakAmp;
		else if (n == decayStart)
			envInc = -volume / (float) decayTime;
		wf.Output1(volume * volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 1 - variable exponential
	/////////////////////////////////////////////////
	phase = 0;
	volume = 0;
	float expMin = 0.2;
	float expMax = 1.0+expMin;
	float expNow = expMin;
	float expMul = pow(expMax/expMin, 1.0f / (float) attackTime);

	for (n = 0; n < totalSamples; n++)
	{
		if (n < attackTime || n > decayStart)
		{
			expNow *= expMul;
			volume = (expNow - expMin) * peakAmp;
		}
		else if (n == attackTime)
		{
			volume = peakAmp;
			expNow = expMax;
		}
		else if (n == decayStart)
		{
			expMul = pow(expMin/expMax, 1.0f / (float) decayTime);
		}
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0.0);

	/////////////////////////////////////////////////
	// Method 1 - log
	/////////////////////////////////////////////////
	phase = 0;
	volume = 0;
	expNow = expMax;
	expMul = pow(expMin/expMax, 1.0f / (float) attackTime);

	for (n = 0; n < totalSamples; n++)
	{
		if (n < attackTime || n > decayStart)
		{
			expNow *= expMul;
			volume = (1.0f - (expNow - expMin)) * peakAmp;
		}
		else if (n == attackTime)
		{
			volume = peakAmp;
			expNow = expMin;
		}
		else if (n == decayStart)
			expMul = pow(expMax/expMin, 1.0f / (float) decayTime);
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 1 - dB
	/////////////////////////////////////////////////
	phase = 0;
	volume = 0;
	float dbLevel = -96;
	float dbIncr = 96.0 / attackTime;

	for (n = 0; n < totalSamples; n++)
	{
		if (n < attackTime || n > decayStart)
		{
			dbLevel += dbIncr;
			volume = pow(10.0, dbLevel / 20.0);
		}
		else if (n == attackTime)
		{
			volume = 1.0;
			dbLevel = 0.0;
		}
		else if (n == decayStart)
		{
			dbIncr = -96.0 / decayTime;
		}
		wf.Output1(peakAmp * volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 2 - simple state machine
	/////////////////////////////////////////////////
	long envCount = attackTime;
	int  envState = 0;

	envInc = peakAmp / (float) attackTime;

	phase = 0;
	volume = 0;

	for (n = 0; n < totalSamples; n++)
	{
		switch (envState)
		{
		case 0:
			if (envCount > 0)
			{
				volume += envInc;
				envCount--;
			}
			else
			{
				volume = peakAmp;
				envCount = sustainTime;
				envState = 1;
			}
			break;
		case 1:
			if (envCount > 0)
				envCount--;
			else
			{
				envCount = decayTime;
				envInc = volume / (float) decayTime;
				envState = 2;
			}
			break;
		case 2:
			if (envCount > 0)
			{
				volume -= envInc;
				envCount--;
			}
			else
			{
				volume = 0;
				envState = 3;
			}
			break;
		case 3:
			break;
		}
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 3 - multiple segments (ADSR)
	/////////////////////////////////////////////////
	float envPeak;
	float envStep;
	float envLevel[4];
	float envIncr[4];
	long  envTime[4];
	int maxEnvIndex = 4;
	int envIndex = -1;

	envLevel[0] = 1.0 * peakAmp;
	envLevel[1] = 0.7 * peakAmp;
	envLevel[2] = 0.7 * peakAmp;
	envLevel[3] = 0.0;
	envTime[0] = (long) (0.1 * synthParams.sampleRate);
	envTime[1] = (long) (0.2 * synthParams.sampleRate);
	envTime[2] = (long) (0.5 * synthParams.sampleRate);
	envTime[3] = (long) (0.2 * synthParams.sampleRate);

	// pre-calculate increments
	envIncr[0] = envLevel[0] / envTime[0];
	for (n = 1; n < maxEnvIndex; n++)
	{
		if (envTime[n] > 0)
			envIncr[n] = (envLevel[n] - envLevel[n-1]) / envTime[n];
		else
			envIncr[n] = (envLevel[n] - envLevel[n-1]);
	}

	phase = 0;
	volume = 0;
	envCount = 0;
	envPeak = 0;
	envStep = 0;
	for (n = 0; n < totalSamples; n++)
	{
		if (--envCount <= 0)
		{
			volume = envPeak;
			if (++envIndex < maxEnvIndex)
			{
				envCount = envTime[envIndex];
				envStep = envIncr[envIndex];
				envPeak = envLevel[envIndex];
			}
			else
				envStep = 0;
		}
		else
		{
			volume += envStep;
		}
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 4 - multiple segments state machine
	/////////////////////////////////////////////////
	float atkLevel[2];
	float decLevel[2];
	long atkTime[2];
	long decTime[2];
	long atkMaxIndex = 2;
	long decMaxIndex = 2;

	atkLevel[0] = 1.0 * peakAmp;
	atkLevel[1] = 0.7 * peakAmp;
	decLevel[0] = 0.2 * peakAmp;
	decLevel[1] = 0.0;
	atkTime[0] = (long) (0.1 * synthParams.sampleRate);
	atkTime[1] = (long) (0.2 * synthParams.sampleRate);
	decTime[0] = (long) (0.1 * synthParams.sampleRate);
	decTime[1] = (long) (0.2 * synthParams.sampleRate);

	sustainTime = totalSamples - (atkTime[0] + atkTime[1] + decTime[0] + decTime[1]);
	phase = 0;
	volume = 0;
	envCount = 0;
	envIndex = -1;
	envState = 0;
	envPeak = 0;

	for (n = 0; n < totalSamples; n++)
	{
		switch (envState)
		{
		case 0: // attack
			if (--envCount <= 0)
			{
				volume = envPeak;
				if (++envIndex < atkMaxIndex)
				{
					envPeak = atkLevel[envIndex];
					envCount = atkTime[envIndex];
					if (envCount < 1)
						envCount = 1;
					envStep = (envPeak - volume) / envCount;
				}
				else
				{
					envCount = sustainTime;
					envStep = 0.0;
					envState = 1;
				}
			}
			else
				volume += envStep;
			break;
		case 1: // sustain
			if (--envCount <= 0)
			{
				envIndex = -1;
				envState = 2;
			}
			break;
		case 2: // release
			if (--envCount <= 0)
			{
				volume = envPeak;
				if (++envIndex < decMaxIndex)
				{
					envPeak = decLevel[envIndex];
					envCount = decTime[envIndex];
					if (envCount < 1)
						envCount = 1;
					envStep = (envPeak - volume) / envCount;
				}
				else
				{
					envCount = 0;
					envStep = 0.0;
					volume = 0.0;
					envState = 3;
				}
			}
			else
				volume += envStep;
			break;
		case 3:
			break;
		}
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}
	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 5 - constant rate ADSR
	/////////////////////////////////////////////////
	phase = 0;
	volume = 0;
	envState = 0;
	float sustainAmpCR = 0.8;
	float atkTimeCR = 0.1;
	float decTimeCR = 0.5;
	float relTimeCR = 0.5;
	float atkIncrCR = 1.0 / (atkTimeCR * synthParams.sampleRate);
	float decIncrCR = 1.0 / (decTimeCR * synthParams.sampleRate);
	float relIncrCR = 1.0 / (relTimeCR * synthParams.sampleRate);

	float susTimeCR = 0;

	for (n = 0; n < totalSamples; n++)
	{
		switch (envState)
		{
		case 0:
			if ((volume += atkIncrCR) >= 1.0)
			{
				volume = 1.0;
				envState = 1;
			}
			break;
		case 1:
			if ((volume -= decIncrCR) <= sustainAmpCR)
			{
				volume = sustainAmpCR;
				envState = 2;
				// for testing. This type envelope would normally sustain until release signal.
				susTimeCR = totalSamples - n - ((relTimeCR * synthParams.sampleRate) * sustainAmpCR);
			}
			break;
		case 2:
			if (--susTimeCR <= 0)
				envState = 3;
			break;
		case 3:
			if ((volume -= decIncrCR) <= 0)
			{
				volume = 0;
				envState = 4;
			}
			break;
		}
		wf.Output1(volume * volume * sinv(phase)); // convex curve
		//wf.Output1(volume * sinv(phase)); // linear
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}
	for (n = 0; n < silence; n++)
		wf.Output1(0);

	/////////////////////////////////////////////////
	// Method 5 - constant rate ADSR, transformed
	/////////////////////////////////////////////////

	float envTblLen = 960; // 96 dB range
	float envTblNdx = 0;
	float atkTblCR[960];
	float decTblCR[960];
	atkTblCR[0] = 0.0;
	decTblCR[0] = 0.0;
	for (n = 1; n < envTblLen; n++)
	{
		volume = pow(10, (double)(959 - n) / -200.0);
		atkTblCR[n] = volume;
		decTblCR[n] = volume;
	}

	sustainAmpCR = 0.5;
	atkIncrCR = 960.0 / (atkTimeCR * synthParams.sampleRate);
	decIncrCR = 960.0 / (decTimeCR * synthParams.sampleRate);
	relIncrCR = 960.0 / (relTimeCR * synthParams.sampleRate);

	susTimeCR = totalSamples - ((relTimeCR * synthParams.sampleRate) * sustainAmpCR);
	phase = 0;
	volume = 0;
	envState = 0;
	for (n = 0; n < totalSamples; n++)
	{
		switch (envState)
		{
		case 0:
			if ((envTblNdx += atkIncrCR) >= envTblLen)
			{
				envTblNdx = envTblLen-1;
				envState = 1;
			}
			volume = atkTblCR[(int)envTblNdx];
			break;
		case 1:
			if ((envTblNdx -= decIncrCR) < 0)
				envTblNdx = 0;
			volume = decTblCR[(int)envTblNdx];
			if (volume <= sustainAmpCR)
			{
				volume = sustainAmpCR;
				envState = 2;
				susTimeCR = totalSamples - n - ((relTimeCR * synthParams.sampleRate) * sustainAmpCR);
			}
			break;
		case 2:
			if (--susTimeCR <= 0)
				envState = 3;
			break;
		case 3:
			if ((envTblNdx -= decIncrCR) <= 0)
			{
				envTblNdx = 0;
				envState = 4;
			}
			volume = decTblCR[(int)envTblNdx];
			break;
		}
		wf.Output1(volume * sinv(phase));
		if ((phase += phaseIncr) >= twoPI)
			phase -= twoPI;
	}

	for (n = 0; n < silence; n++)
		wf.Output1(0);

	wf.CloseWaveFile();

	int oor = wf.GetOOR();
	if (oor)
		printf("%d Samples out of range...\n", oor);

	return 0;
}