I've included all the code I've written so far, because I wasn't sure if anyone wanted to try to replicate the error. It might be too much, but I didn't want to leave anything out in case that's what was causing the error.
#include
using namespace std;
#include "olcNoiseMaker.h"
The line above shows what library I'm using, here's a link to the Github page where I got it from: https://github.com/OneLoneCoder/synth
//Converts frequency (Hz) to angular velocity
double w(double dHertz)
{
return dHertz * 2.0 * PI;
}
atomic<double> dFrequencyOutput = 0.0;
double dOctaveBaseFrequency = 220.0; //A3
double d12thRootOf2 = pow(2.0, 1.0 / 12.0);
sEnvelopeADSR envelope;
double osc(double dHertz, double dTime, int nType)
{
switch (nType)
{
case 0: // Sine Wave
return sin(w(dHertz) * dTime);
case 1: // Square Wave
return sin(w(dHertz) * dTime) > 0 ? 1.0 : -1.0;
case 2: // Triangle Wave
return asin(sin(w(dHertz) * dTime)) * 2.0 / PI;
case 3: // Saw Wave (analogue / warm / slow)
{
double dOutput = 0.0;
for (double n = 1.0; n < 100.0; n++)
dOutput += (sin(n * w(dHertz) * dTime)) / n;
return dOutput * (2.0 / PI);
}
case 4: // Saw Wave (optimised / harsh / fast)
return (2.0 / PI) * (dHertz * PI * fmod(dTime, 1.0 / dHertz) - (PI / 2.0));
case 5: // Psuedo Random Noise
return 2.0 * ((double)rand() / (double)RAND_MAX) - 1.0;
default:
return 0.0;
}
}
struct sEnvelopeADSR
{
double dAttackTime;
double dDecayTime;
double dReleaseTime;
double dSustainAmplitude;
double dStartAmplitude;
double dTriggerOnTime;
double dTriggerOffTime;
bool bNoteOn;
sEnvelopeADSR()
{
dAttackTime = 0.01;
dDecayTime = 0.01;
dStartAmplitude = 1.0;
dSustainAmplitude = 0.8;
dReleaseTime = 0.02;
dTriggerOnTime = 0.0;
dTriggerOffTime = 0.0;
bNoteOn = false;
}
// Call when key is pressed
void NoteOn(double dTimeOn)
{
dTriggerOnTime = dTimeOn;
bNoteOn = true;
}
// Call when key is released
void NoteOff(double dTimeOff)
{
dTriggerOffTime = dTimeOff;
bNoteOn = false;
}
// Get the correct Amplitude at the requested point in time
double GetAmplitude(double dTime)
{
double dAmplitude = 0.0;
double dLifeTime = dTime - dTriggerOnTime;
if (bNoteOn)
{
// ADS
// Attack
if (dLifeTime <= dAttackTime) {
dAmplitude = (dLifeTime / dAttackTime) * dStartAmplitude;
}
// Decay
if (dLifeTime > dAttackTime && dLifeTime <= (dAttackTime + dDecayTime)) {
dAmplitude = ((dLifeTime - dAttackTime) / dDecayTime) * (dSustainAmplitude - dStartAmplitude) + dStartAmplitude;
}
// Sustain
if (dLifeTime > (dAttackTime + dDecayTime))
{
dAmplitude = dSustainAmplitude;
}
else
{
// Release
dAmplitude = ((dTime - dTriggerOffTime) / dReleaseTime) * (0.0 - dSustainAmplitude) + dSustainAmplitude;
}
if (dAmplitude <= 0.0001)
{
dAmplitude = 0;
}
return dAmplitude;
}
}
}
// Function used by olcNoiseMaker to generate sound
// Returns amplitude(-1.0 to + 1.0) as a function of time
double MakeNoise(double dTime)
The line above is where I'm having the problem. In Visual Studio 2019 Community Edition, I get an error saying that a semicolon is needed somewhere before it. I don't understand the issue
{
}
int main()
{
wcout << "onelonecoder.com - Synthesizer Part 1" << endl;
// Get all sound behaviors
vector<wstring> devices = olcNoiseMaker<short>::Enumerate();
//Display findings
for (auto d : devices) wcout << "Found Output Device:" << d << endl;
// Create sound machine!!
olcNoiseMaker<short> sound(devices[0], 44100, 1, 8, 512);
// Link noise function with sound machine
sound.SetUserFunction(MakeNoise);
while (1)
{
//Add a keyboard like a piano
bool bKeyPressed = false;
for (int k = 0; k < 15; k++)
{
if (GetAsyncKeyState((unsigned char)("ZSXCFVGBNJMK\xbcL\xbe\xbf"[k])) & 0x8000)
{
dFrequencyOutput = dOctaveBaseFrequency * pow(d12thRootOf2, k);
envelope.bNoteOn(sound.GetTime());
bKeyPressed = true;
}
}
if (!bKeyPressed)
{
envelope.bNoteOff(sound.GetTime());
}
return 0;
}
}
The end of a struct
or class
definition needs a ;
after it, even though it ends with a }
. This is one of those mistakes you usually only make once.
The reason for this is so that you can simultaneously declare the struct/class and create a variable of that type, by putting the variable name before the ;
. This was used more often in C, you don't see it so much in C++.