Error checks and comments

main
Thor 1 year ago
parent 84c63f98ed
commit 30a3493354
  1. 35
      main.cpp
  2. 12
      oscillator.h
  3. 10
      svf.h

@ -25,6 +25,7 @@ typedef struct {
PmStream* pmStream; PmStream* pmStream;
} State; } State;
// PortAudio callback for audio I/O
static int paCallback( static int paCallback(
const void *inputBuffer, const void *inputBuffer,
void *outputBuffer, void *outputBuffer,
@ -53,6 +54,7 @@ static int paCallback(
return 0; return 0;
} }
// PortTimer callback for MIDI I/O
static void ptCallback(PtTimestamp timestamp, void* userData) { static void ptCallback(PtTimestamp timestamp, void* userData) {
State* state = (State*) userData; State* state = (State*) userData;
PmEvent events[8]; PmEvent events[8];
@ -116,6 +118,7 @@ int main(void) {
state.filter.setQ(1); state.filter.setQ(1);
state.time = 0; state.time = 0;
// Initialise PortMIDI and PortAudio libraries
PmError pmErr = Pm_Initialize(); PmError pmErr = Pm_Initialize();
if(pmErr != pmNoError) { if(pmErr != pmNoError) {
handlePMError(pmErr); handlePMError(pmErr);
@ -134,17 +137,18 @@ int main(void) {
} }
cout << i << ". " << deviceInfo->name << endl; cout << i << ". " << deviceInfo->name << endl;
} }
int pmDeviceIndex; int pmDeviceIndex;
for(;;) { for(;;) { // loop for input until valid choice is made
string input; string input;
getline(cin, input); getline(cin, input);
try { try {
pmDeviceIndex = stoi(input); pmDeviceIndex = stoi(input);
if(pmDeviceIndex >= 0 && pmDeviceIndex < pmDeviceCount) { if( pmDeviceIndex >= 0 &&
pmDeviceIndex < pmDeviceCount &&
Pm_GetDeviceInfo(pmDeviceIndex)->input) {
break; break;
} }
} catch(...) { } } catch(...) { } // stoi() throws an exeption for invalid integers
cout << "Invalid selection" << endl; cout << "Invalid selection" << endl;
} }
@ -158,32 +162,34 @@ int main(void) {
cout << i << ". " << deviceInfo->name << " (" << Pa_GetHostApiInfo(deviceInfo->hostApi)->name << ")" << endl; cout << i << ". " << deviceInfo->name << " (" << Pa_GetHostApiInfo(deviceInfo->hostApi)->name << ")" << endl;
} }
PaHostApiIndex paDeviceIndex; PaHostApiIndex paDeviceIndex;
for(;;) { for(;;) { // loop for input until valid choice is made
string input; string input;
getline(cin, input); getline(cin, input);
try { try {
paDeviceIndex = stoi(input); paDeviceIndex = stoi(input);
if(paDeviceIndex >= 0 && paDeviceIndex < paDeviceCount) { if( paDeviceIndex >= 0 &&
paDeviceIndex < paDeviceCount &&
Pa_GetDeviceInfo(paDeviceIndex)->maxOutputChannels >= 2) {
break; break;
} }
} catch(...) { } } catch(...) { } // stoi() throws an exeption for invalid integers
cout << "Invalid selection" << endl; cout << "Invalid selection" << endl;
} }
// Start MIDI timer and open MIDI input
Pt_Start(1, ptCallback, &state); Pt_Start(1, ptCallback, &state);
PmError pmError = Pm_OpenInput( PmError pmError = Pm_OpenInput(
&state.pmStream, &state.pmStream,
pmDeviceIndex, pmDeviceIndex,
NULL, NULL,
256, 8,
NULL, NULL,
NULL); NULL);
if(pmErr != pmNoError) { if(pmErr != pmNoError) {
handlePMError(pmErr); handlePMError(pmErr);
} }
/* Open an audio I/O stream. */ // Configure/start audio output stream
PaStream *paStream; PaStream *paStream;
PaStreamParameters paStreamParams; PaStreamParameters paStreamParams;
paStreamParams.device = paDeviceIndex; paStreamParams.device = paDeviceIndex;
@ -193,17 +199,16 @@ int main(void) {
paStreamParams.hostApiSpecificStreamInfo = NULL; paStreamParams.hostApiSpecificStreamInfo = NULL;
paErr = Pa_OpenStream( paErr = Pa_OpenStream(
&paStream, &paStream,
NULL, /* no input channels */ NULL, /* no input channels */
&paStreamParams, /* stereo output */ &paStreamParams, /* stereo output */
SAMPLE_RATE, SAMPLE_RATE,
0, /* frames per buffer */ 0, /* frames per buffer */
paNoFlag, paNoFlag,
paCallback, paCallback,
&state); &state);
if(paErr != paNoError) { if(paErr != paNoError) {
handlePAError(paErr); handlePAError(paErr);
} }
paErr = Pa_StartStream(paStream); paErr = Pa_StartStream(paStream);
if(paErr != paNoError) { if(paErr != paNoError) {
handlePAError(paErr); handlePAError(paErr);
@ -212,7 +217,7 @@ int main(void) {
const PaStreamInfo *paStreamInfo = Pa_GetStreamInfo(paStream); const PaStreamInfo *paStreamInfo = Pa_GetStreamInfo(paStream);
cout << "Latency: " << round(1000 * paStreamInfo->outputLatency) << " ms" << endl; cout << "Latency: " << round(1000 * paStreamInfo->outputLatency) << " ms" << endl;
/* Wait for Return key */ // Wait for Return key
cout << "Running - press Enter to exit" << endl; cout << "Running - press Enter to exit" << endl;
getchar(); getchar();

@ -11,9 +11,9 @@ public:
enum Mode { MODE_SINE, MODE_SAW, MODE_SQUARE }; enum Mode { MODE_SINE, MODE_SAW, MODE_SQUARE };
Mode mode; Mode mode;
float phase; float phase; // current waveform phase angle (radians)
float phaseStep; float phaseStep; // phase angle step per sample
float value; float value; // current amplitude value
Oscillator(); Oscillator();
@ -41,7 +41,7 @@ public:
else return 0.0; else return 0.0;
} }
// This class provides a band-limited oscillator // Generate next output sample and advance the phase angle
float tick() { float tick() {
float t = phase / PIx2; // Define half phase float t = phase / PIx2; // Define half phase
@ -61,10 +61,10 @@ public:
} }
phase += phaseStep; phase += phaseStep;
if(phase >= PIx2) { if(phase >= PIx2) { // wrap if phase angle >=360º
phase -= PIx2; phase -= PIx2;
} }
return value; // Output return value;
} }
}; };

10
svf.h

@ -18,11 +18,11 @@ protected:
public: public:
typedef struct { typedef struct {
float hp; float hp; // high-pass
float bp; float bp; // band-pass
float lp; float lp; // low-pass
float br; float br; // band-reject
float ap; float ap; // all-pass
} Output; } Output;
SVF() { SVF() {

Loading…
Cancel
Save