#include "speech.h"
#include "loop.h"
#include "mario.h"
SoundGenerator soundGenerator;
void setup()
{
PS2Controller.
begin(PS2Preset::KeyboardPort0_MousePort1, KbdMode::GenerateVirtualKeys);
DisplayController.begin();
}
class ChannelFrame : public uiFrame {
SineWaveformGenerator sine;
SquareWaveformGenerator square;
NoiseWaveformGenerator noise;
TriangleWaveformGenerator triangle;
SawtoothWaveformGenerator sawtooth;
SamplesGenerator loop = SamplesGenerator(loopSamples, sizeof(loopSamples));
SamplesGenerator speech = SamplesGenerator(speechSamples, sizeof(speechSamples));
SamplesGenerator mario = SamplesGenerator(marioSamples, sizeof(marioSamples));
WaveformGenerator * curGen = nullptr;
uiLabel * volumeLabel, * frequencyLabel;
uiSlider * volumeSlider, * frequencySlider;
uiComboBox * genComboBox;
uiCheckBox * enableCheck;
public:
ChannelFrame(uiWindow * parent)
: uiFrame(parent, "", Point(0, 0), Size(408, 80))
{
static int channel_ = 0;
static int y = 4, x = 4;
static int startingFreq = 150;
app()->moveWindow(this, x, y);
y += size().height + 4;
if (y + size().
height > parent->size().height) {
x += 25;
y = x;
}
frameProps().resizeable = false;
frameProps().hasCloseButton = false;
setTitleFmt("Channel %d", ++channel_);
volumeLabel = new uiLabel(this, "", Point(5, 20));
volumeSlider = new uiSlider(this, Point(72, 19), Size(150, 17), uiOrientation::Horizontal);
volumeSlider->onChange = [&]() {
volumeLabel->setTextFmt("Volume %d", volumeSlider->position());
if (curGen)
curGen->setVolume(volumeSlider->position());
};
volumeSlider->setup(0, 127, 16);
volumeSlider->setPosition(100);
new uiLabel(this, "Type", Point(230, 20));
genComboBox = new uiComboBox(this, Point(260, 20), Size(140, 16), 35);
genComboBox->listBoxStyle().textFont = &fabgl::FONT_std_12;
genComboBox->textEditStyle().textFont = &fabgl::FONT_std_12;
genComboBox->items().append("Sine Wave");
genComboBox->items().append("Square Wave");
genComboBox->items().append("Triangle Wave");
genComboBox->items().append("Sawtooth Wave");
genComboBox->items().append("Noise");
genComboBox->items().append("Loop");
genComboBox->items().append("Speech");
genComboBox->items().append("Mario");
genComboBox->selectItem(0);
genComboBox->onChange = [&]() {
setGenerator(genComboBox->selectedItem());
};
frequencyLabel = new uiLabel(this, "", Point(5, 39));
frequencySlider = new uiSlider(this, Point(72, 38), Size(330, 17), uiOrientation::Horizontal);
frequencySlider->onChange = [&]() {
frequencyLabel->setTextFmt("Freq %d Hz", frequencySlider->position());
if (curGen)
curGen->setFrequency(frequencySlider->position());
};
frequencySlider->setup(0, 8000, 500);
frequencySlider->setPosition(startingFreq);
startingFreq += 50;
new uiLabel(this, "Enable", Point(5, 76-17));
enableCheck = new uiCheckBox(this, Point(77, 75-17), Size(17, 17));
enableCheck->onChange = [&]() {
if (curGen)
curGen->enable(enableCheck->checked());
};
setGenerator(0);
}
void setGenerator(int index) {
soundGenerator.detach(curGen);
switch (index) {
case 0:
curGen = &sine;
break;
case 1:
curGen = □
break;
case 2:
curGen = ▵
break;
case 3:
curGen = &sawtooth;
break;
case 4:
curGen = &noise;
break;
case 5:
curGen = &loop;
break;
case 6:
curGen = &speech;
break;
case 7:
curGen = &mario;
break;
}
soundGenerator.attach(curGen);
curGen->enable(enableCheck->checked());
curGen->setFrequency(frequencySlider->position());
}
};
class CommandsFrame : public uiFrame {
public:
CommandsFrame(uiWindow * parent)
: uiFrame(parent, "Main Controls", Point(500, 4), Size(133, 200))
{
frameStyle().titleFont = &fabgl::FONT_std_12;
frameProps().resizeable = false;
frameProps().hasMaximizeButton = false;
frameProps().hasMinimizeButton = false;
frameProps().hasCloseButton = false;
uiButton * addChannelBtn = new uiButton(this, "Add Channel", Point(7, 22), Size(80, 16));
addChannelBtn->onClick = [=]() {
if (heap_caps_get_free_size(MALLOC_CAP_8BIT) < 5000)
app()->messageBox("Out of memory!", "I'm sorry, there is no more memory available!", "OK");
else
new ChannelFrame(parent);
};
uiButton * resetBtn = new uiButton(this, "Reset", Point(7, 45), Size(80, 16));
resetBtn->onClick = [=]() {
if (app()->messageBox("Reset ESP32", "Are you sure?", "Yes", "No", nullptr, uiMessageBoxIcon::Question) == uiMessageBoxResult::Button1)
ESP.restart();
};
uiLabel * volumeLabel = new uiLabel(this, "", Point(90, 182));
uiSlider * volumeSlider = new uiSlider(this, Point(100, 20), Size(17, 160), uiOrientation::Vertical);
volumeSlider->onChange = [=]() {
volumeLabel->setTextFmt("Vol %d", volumeSlider->position());
soundGenerator.setVolume(volumeSlider->position());
};
volumeSlider->setup(0, 127, 16);
volumeSlider->setPosition(100);
}
};
class MyApp : public uiApp {
void init() {
rootWindow()->frameStyle().backgroundColor = RGB888(0, 0, 64);
new ChannelFrame(rootWindow());
new ChannelFrame(rootWindow());
new ChannelFrame(rootWindow());
new ChannelFrame(rootWindow());
new CommandsFrame(rootWindow());
soundGenerator.play(true);
}
} app;
void loop()
{
app.run(&DisplayController);
}
static void begin(gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO, gpio_num_t port1_clkGPIO=GPIO_UNUSED, gpio_num_t port1_datGPIO=GPIO_UNUSED)
Initializes PS2 device controller.
The PS2 device controller class.
Represents the VGA bitmapped controller.
This file is the all in one include file. Application can just include this file to use FabGL library...
#define VGA_640x350_70HzAlt1
This file contains all classes related to FabGL Graphical User Interface.