72 "Test_Oscillators.cpp",
88 printf(
"\nMenu List\n");
90 unsigned numSuites = 7;
92 unsigned numSuites = 6;
94 for (
unsigned i = 0; i < numSuites; i++) {
95 gTestList = allTests[i];
99 for (
unsigned j = 0; gTestList[j].
name != NULL; j++) {
100 printf(
"%24s %s\n", gTestList[j].name, gTestList[j].comment);
120 #define WRITE_TO_FILE // support file recording
132 if (thr->isThreadRunning())
135 if (this->threadShouldExit())
137 if ( ! thr->isThreadRunning()) {
143 thr->signalThreadShouldExit();
145 comp->playing =
false;
146 const juce::MessageManagerLock mmLock;
147 if (comp->isTimerRunning())
167 playButton.reset (
new TextButton (
"playNote"));
168 addAndMakeVisible (playButton.get());
169 playButton->setButtonText (TRANS(
"Play/Stop"));
170 playButton->addListener (
this);
172 quitButton.reset (
new TextButton (
"quitAction"));
173 addAndMakeVisible (quitButton.get());
174 quitButton->setButtonText (TRANS(
"Quit"));
175 quitButton->addListener (
this);
177 testCombo.reset (
new ComboBox (
"test to run"));
178 addAndMakeVisible (testCombo.get());
179 testCombo->setEditableText (
false);
180 testCombo->setJustificationType (Justification::centredLeft);
181 testCombo->setTextWhenNothingSelected (String());
182 testCombo->setTextWhenNoChoicesAvailable (TRANS(
"(no choices)"));
183 testCombo->addListener (
this);
186 addAndMakeVisible (oscilloscopeL.get());
187 oscilloscopeL->setName (
"new component");
189 label.reset (
new Label (
"CSL test",
190 TRANS(
"CSL 6.0 Demos - select from the menus at the lower-left")));
191 addAndMakeVisible (label.get());
192 label->setFont (Font (Font::getDefaultSerifFontName(), 24.00f, Font::plain).withTypefaceStyle (
"Bold"));
193 label->setJustificationType (Justification::centred);
194 label->setEditable (
false,
false,
false);
195 label->setColour (Label::textColourId, Colour (0xfffffc00));
196 label->setColour (TextEditor::textColourId, Colours::black);
197 label->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
199 prefsButton.reset (
new TextButton (
"new button"));
200 addAndMakeVisible (prefsButton.get());
201 prefsButton->setButtonText (TRANS(
"Audio Prefs"));
202 prefsButton->addListener (
this);
204 prefsButton->setBounds (8, 8, 144, 32);
206 cpuLabel.reset (
new Label (
"new label",
208 addAndMakeVisible (cpuLabel.get());
209 cpuLabel->setFont (Font (Font::getDefaultSansSerifFontName(), 15.00f, Font::plain).withTypefaceStyle (
"Bold"));
210 cpuLabel->setJustificationType (Justification::centredRight);
211 cpuLabel->setEditable (
false,
false,
false);
212 cpuLabel->setColour (TextEditor::textColourId, Colours::black);
213 cpuLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
216 addAndMakeVisible (oscilloscopeR.get());
217 oscilloscopeR->setName (
"new component");
219 VUMeterL.reset (
new VUMeter());
220 addAndMakeVisible (VUMeterL.get());
221 VUMeterL->setName (
"new component");
223 VUMeterR.reset (
new VUMeter());
224 addAndMakeVisible (VUMeterR.get());
225 VUMeterR->setName (
"new component");
227 scaleSlider.reset (
new Slider (
"new slider"));
228 addAndMakeVisible (scaleSlider.get());
229 scaleSlider->setRange (0, 1, 0);
230 scaleSlider->setSliderStyle (Slider::LinearHorizontal);
231 scaleSlider->setTextBoxStyle (Slider::NoTextBox,
true, 80, 20);
232 scaleSlider->addListener (
this);
234 amplitudeSlider.reset (
new Slider (
"new slider"));
235 addAndMakeVisible (amplitudeSlider.get());
236 amplitudeSlider->setRange (-5, 5, 0);
237 amplitudeSlider->setSliderStyle (Slider::LinearVertical);
238 amplitudeSlider->setTextBoxStyle (Slider::NoTextBox,
true, 8, 20);
239 amplitudeSlider->addListener (
this);
241 loopButton.reset (
new ToggleButton (
"new toggle button"));
242 addAndMakeVisible (loopButton.get());
243 loopButton->setButtonText (TRANS(
"Loop"));
244 loopButton->addListener (
this);
246 familyCombo.reset (
new ComboBox (
"test family"));
247 addAndMakeVisible (familyCombo.get());
248 familyCombo->setEditableText (
false);
249 familyCombo->setJustificationType (Justification::centredLeft);
250 familyCombo->setTextWhenNothingSelected (String());
251 familyCombo->setTextWhenNoChoicesAvailable (TRANS(
"(no choices)"));
252 familyCombo->addItem (TRANS(
"Oscillators"), 1);
253 familyCombo->addItem (TRANS(
"Sources"), 2);
254 familyCombo->addItem (TRANS(
"Envelopes"), 3);
255 familyCombo->addItem (TRANS(
"Effects"), 4);
256 familyCombo->addItem (TRANS(
"Panners"), 5);
257 familyCombo->addItem (TRANS(
"Controls"), 6);
258 familyCombo->addListener (
this);
260 recordButton.reset (
new ToggleButton (
"new toggle button"));
261 addAndMakeVisible (recordButton.get());
262 recordButton->setButtonText (TRANS(
"Record"));
263 recordButton->addListener (
this);
267 oscilloscopeL->initialise(0, 20, 2,
true);
268 oscilloscopeR->initialise(1, 20, 2,
true);
281 const juce::String
error (mAudioDeviceManager.initialise (0,
285 if (
error.isNotEmpty())
286 juce::AlertWindow::showMessageBox (juce::AlertWindow::WarningIcon,
288 "Couldn't open an output device!\n\n" +
error);
290 juce::AudioIODevice* audioIO = mAudioDeviceManager.getCurrentAudioDevice();
292 #ifdef READ_IO_PROPS // overwrite the system frame rate and block size from the
294 unsigned sRate = (unsigned) audioIO->getCurrentSampleRate();
295 unsigned bufSize = audioIO->getCurrentBufferSizeSamples();
296 theIO =
new csl::IO(sRate, bufSize, -1, -1,
300 #else // reset the HW frame rate & block size to the CSL definition
301 juce::AudioDeviceManager::AudioDeviceSetup setup;
302 mAudioDeviceManager.getAudioDeviceSetup(setup);
305 mAudioDeviceManager.setAudioDeviceSetup(setup,
true);
314 mAudioDeviceManager.addAudioCallback(
this);
325 amplitudeSlider->setValue(0.8);
326 scaleSlider->setValue(0.1);
327 oscilloscopeL->start();
328 oscilloscopeR->start();
329 VUMeterL->setChannel(0);
330 VUMeterR->setChannel(1);
331 loopButton->setToggleState (
false,
false);
338 if (initMsg.size() > 0) {
339 sscanf(initMsg.c_str(),
"%d %d", & whichSuite, & whichTest);
340 printf(
"Select suite %d, test %d\n", whichSuite, whichTest);
349 familyCombo->setSelectedId(whichSuite,
true);
350 this->setComboLabels(whichSuite - 1);
351 testCombo->setSelectedId(whichTest,
true);
363 mAudioDeviceManager.removeAudioCallback(
this);
371 playButton =
nullptr;
372 quitButton =
nullptr;
374 oscilloscopeL =
nullptr;
376 prefsButton =
nullptr;
378 oscilloscopeR =
nullptr;
381 scaleSlider =
nullptr;
382 amplitudeSlider =
nullptr;
383 loopButton =
nullptr;
384 familyCombo =
nullptr;
385 recordButton =
nullptr;
398 g.fillAll (Colours::grey);
409 playButton->setBounds (380, getHeight() - 39, 136, 32);
410 quitButton->setBounds (getWidth() - 8 - 176, 8, 176, 32);
411 testCombo->setBounds (184, getHeight() - 35, 176, 24);
412 oscilloscopeL->setBounds (44, 48, getWidth() - 52, proportionOfHeight (0.4200f));
413 label->setBounds (436 - (558 / 2), 10, 558, 28);
414 cpuLabel->setBounds (getWidth() - 64, getHeight() - 35, 56, 24);
415 oscilloscopeR->setBounds (44, proportionOfHeight (0.5000f), getWidth() - 52, proportionOfHeight (0.4200f));
416 VUMeterL->setBounds (25, 48, 15, roundToInt (proportionOfHeight (0.4200f) * 1.0000f));
417 VUMeterR->setBounds (24, proportionOfHeight (0.5000f), 15, roundToInt (proportionOfHeight (0.4200f) * 1.0000f));
418 scaleSlider->setBounds (36, getHeight() - 60, getWidth() - 36, 24);
419 amplitudeSlider->setBounds (0, 42, 20, proportionOfHeight (0.8700f));
420 loopButton->setBounds (380 + 136 - -24, getHeight() - 11 - 24, 64, 24);
421 familyCombo->setBounds (48, getHeight() - 35, 128, 24);
422 recordButton->setBounds ((getWidth() - 8 - 176) + -12 - 72, 37 - 24, 72, 24);
432 if (buttonThatWasClicked == playButton.get())
440 else if (buttonThatWasClicked == quitButton.get())
446 juce::JUCEApplication::quit();
450 else if (buttonThatWasClicked == prefsButton.get())
456 oscilloscopeL->stop();
457 oscilloscopeR->stop();
471 juce::AudioDeviceSelectorComponent audioSettingsComp (mAudioDeviceManager,
477 audioSettingsComp.setSize (500, 400);
478 juce::DialogWindow::showModalDialog (
"Audio Settings",
481 juce::Colours::azure,
484 oscilloscopeL->start();
485 oscilloscopeR->start();
492 else if (buttonThatWasClicked == loopButton.get())
498 loopThread->stopThread(100);
507 else if (buttonThatWasClicked == recordButton.get())
511 bool wasRec = recrding;
528 if (comboBoxThatHasChanged == testCombo.get())
536 else if (comboBoxThatHasChanged == familyCombo.get())
541 this->setComboLabels(familyCombo->getSelectedId() - 1);
555 if (sliderThatWasMoved == scaleSlider.get())
559 unsigned stepValue = (unsigned) (scaleSlider->getValue() * 10.0) + 1;
560 oscilloscopeL->setSamplesToAverage(stepValue);
561 oscilloscopeR->setSamplesToAverage(stepValue);
565 else if (sliderThatWasMoved == amplitudeSlider.get())
569 amplValue = pow(2.0, amplitudeSlider->getValue());
587 int totalNumInputChannels,
588 float** outputChannelData,
589 int totalNumOutputChannels,
592 for (
unsigned i = 0; i < totalNumOutputChannels; i++)
593 memset(outputChannelData[i], 0, numSamples *
sizeof(
float));
601 outBuffer.setSize(totalNumOutputChannels, numSamples);
602 outBuffer.mAreBuffersAllocated =
true;
605 for (
unsigned i = 0; i < totalNumOutputChannels; i++)
606 outBuffer.setBuffer(i, outputChannelData[i]);
612 outBuffer.mIsPopulated =
true;
613 outBuffer.mAreBuffersZero =
false;
618 if (amplValue != 1.0f) {
620 for (
unsigned i = 0; i < totalNumOutputChannels; i++) {
621 float * sampPtr = outputChannelData[i];
623 for (
unsigned j = 0; j < numSamples; j++)
624 *sampPtr++ *= amplValue;
627 oscilloscopeL->audioDeviceIOCallback (inputChannelData, totalNumInputChannels,
628 outputChannelData, totalNumOutputChannels, numSamples);
629 oscilloscopeR->audioDeviceIOCallback (inputChannelData, totalNumInputChannels,
630 outputChannelData, totalNumOutputChannels, numSamples);
631 VUMeterL->audioDeviceIOCallback (inputChannelData, 0,
632 outputChannelData, totalNumOutputChannels, numSamples);
633 VUMeterR->audioDeviceIOCallback (inputChannelData, 0,
634 outputChannelData, totalNumOutputChannels, numSamples);
645 memcpy(sPtr, outputChannelData[0], (numSamples *
sizeof(
csl::sample)));
647 memcpy(sPtr, outputChannelData[1], (numSamples *
sizeof(
csl::sample)));
667 logMsg(
"Write %5.3f sec (%d ksamp) to file \"%s\"\n",
669 SoundFile * ioFile =
new SoundFile(outName);
671 ioFile->writeBuffer(*gFileBuffer);
676 if ( ! gFileBuffer) {
689 oscilloscopeL->audioDeviceAboutToStart (device);
690 oscilloscopeR->audioDeviceAboutToStart (device);
703 gTestList = allTests[which];
704 for (
unsigned i = 0; gTestList[i].
name != NULL; i++) {
706 testCombo->addItem(juce::String(gTestList[i].name), i + 1);
708 testCombo->setSelectedId(1);
720 const juce::MessageManagerLock mmLock;
723 juce::String msgS(msg);
724 gCPULabel->setText(msgS, juce::sendNotification);
731 int which = testCombo->getSelectedId();
735 sprintf(initmsg,
"%d %d", familyCombo->getSelectedId(), testCombo->getSelectedId());
741 ThreadFunc fcn = (
void * (*)(
void *)) gTestList[which - 1].
fcn;
744 playThread->startThread();
745 loopThread =
new LThread(playThread,
this, loop);
746 loopThread->startThread();
748 this->startTimer(1000);
758 loopThread->stopThread(1000);
759 if (playThread->isThreadRunning())
760 playThread->stopThread(1000);
void logMsg(const char *format,...)
These are the public logging messages.
static std::string initFileText(char key)
read/write the init file (typ. ~/.cslrc)
#define kSoundFileFormatAIFF
#define SAMPS_TO_WRITE
record 30 seconds by default
void *(* ThreadFunc)(void *)
This is the CSL_AbstComponent JUCE wrapper for the CSL demos.
unsigned mNumFrames
num frames used in each buffer
bool sleepMsec(float dur)
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
const char * allTestNames[]
void pullInput(Buffer &outBuffer, SampleBuffer out=0)
get a buffer from the CSL graph
static std::string sndFileName()
pick a new sound file name to use based on OUT_SFILE_NAME
static void storeToInitFile(char key, std::string data)
void comboBoxChanged(ComboBox *comboBoxThatHasChanged) override
static unsigned numOutChannels()
default number of output channels
static bool stopNow()
flag to stop threads and timers
static unsigned maxBufferFrames()
the max num frames that can be requested
virtual SampleBuffer buffer(unsigned bufNum)
convenience accessors for sample buffers
const char * allTestFiles[]
GThread takes a CSL test function and runs it.
juce::AudioDeviceManager * gAudioDeviceManager
juce::Component * createCSLComponent()
void freeBuffers()
fcn to free them
static void clearStopNow()
struct used for the JUCE pop-up menu of tests (see the test files)
UnitGenerator * mGraph
the root of my client DSP graph, often a mixer or panner
static unsigned blockSize()
the default block size
float sample
(could be changed to int, or double)
IO – the abstract I/O scheduling class; subclasses interface to specific I/O APIs.
static unsigned frameRate()
default frame rate
void audioDeviceAboutToStart(juce::AudioIODevice *device)
static unsigned numInChannels()
default number of input channels
void audioDeviceStopped()
void setComboLabels(unsigned which)
void buttonClicked(Button *buttonThatWasClicked) override
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
void paint(Graphics &g) override
void allocateBuffers()
fcn to malloc storage buffers
void error(int num, const char *m, const char *path)
void sliderValueChanged(Slider *sliderThatWasMoved) override
testStruct audioTestList[]
Base class of CSL exceptions (written upper-case). Has a string message.
void audioDeviceIOCallback(const float **inputChannelData, int totalNumInputChannels, float **outputChannelData, int totalNumOutputChannels, int numSamples)