You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
stmdsp/gui/wxmain_mrun.cpp

238 lines
8.0 KiB
C++

#include "wxmain.hpp"
#include "wxmain_devdata.h"
#include "wxsiggen.hpp"
#include <wx/menuitem.h>
#include <wx/textdlg.h>
void MainFrame::onRunConnect(wxCommandEvent& ce)
{
auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
if (!m_device) {
stmdsp::scanner scanner;
if (auto devices = scanner.scan(); devices.size() > 0) {
m_device = new stmdsp::device(devices.front());
if (m_device->connected()) {
auto rate = m_device->get_sample_rate();
m_rate_select->SetSelection(rate);
updateMenuOptions();
menuItem->SetItemLabel("&Disconnect");
m_status_bar->SetStatusText("Connected.");
} else {
delete m_device;
m_device = nullptr;
menuItem->SetItemLabel("&Connect");
m_status_bar->SetStatusText("Failed to connect.");
}
} else {
m_status_bar->SetStatusText("No devices found.");
}
} else {
delete m_device;
m_device = nullptr;
updateMenuOptions();
menuItem->SetItemLabel("&Connect");
m_status_bar->SetStatusText("Disconnected.");
}
}
void MainFrame::onRunStart(wxCommandEvent& ce)
{
auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
if (!m_is_running) {
if (m_run_measure->IsChecked()) {
m_device->continuous_start_measure();
m_timer_performance->StartOnce(1000);
} else {
auto reqSpeedExact =
m_device->get_buffer_size()
/ static_cast<float>(srateNums[m_rate_select->GetSelection()])
* 1000.f * 0.5f;
int reqSpeed = reqSpeedExact;
if (m_device->is_siggening() && m_wav_clip)
m_timer_wavclip->Start(reqSpeed);
if (m_conv_result_log || m_run_draw_samples->IsChecked())
m_timer_record->Start(reqSpeed);
m_device->continuous_start();
}
m_rate_select->Enable(false);
menuItem->SetItemLabel("&Stop");
m_status_bar->SetStatusText("Running.");
m_is_running = true;
} else {
m_device->continuous_stop();
m_timer_performance->Stop();
m_timer_record->Stop();
m_timer_wavclip->Stop();
m_rate_select->Enable(true);
menuItem->SetItemLabel("&Start");
m_status_bar->SetStatusText("Ready.");
m_is_running = false;
if (m_run_draw_samples->IsChecked())
m_compile_output->Refresh();
}
updateMenuOptions();
}
void MainFrame::onRunLogResults(wxCommandEvent& ce)
{
auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
if (menuItem->IsChecked()) {
wxFileDialog dialog (this, "Choose log file", "", "", "*.csv",
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (dialog.ShowModal() != wxID_CANCEL) {
if (m_conv_result_log) {
m_conv_result_log->Close();
delete m_conv_result_log;
m_conv_result_log = nullptr;
}
m_conv_result_log = new wxFileOutputStream(dialog.GetPath());
}
m_status_bar->SetStatusText("Ready.");
} else if (m_conv_result_log) {
m_conv_result_log->Close();
delete m_conv_result_log;
m_conv_result_log = nullptr;
}
}
void MainFrame::onRunEditBSize(wxCommandEvent&)
{
wxTextEntryDialog dialog (this, "Enter new buffer size (100-4096)", "Set Buffer Size");
if (dialog.ShowModal() == wxID_OK) {
if (wxString value = dialog.GetValue(); !value.IsEmpty()) {
if (unsigned long n; value.ToULong(&n)) {
if (n >= 100 && n <= stmdsp::SAMPLES_MAX) {
if ((n & 1) == 1)
++n;
m_device->continuous_set_buffer_size(n);
} else {
m_status_bar->SetStatusText("Error: Invalid buffer size.");
}
} else {
m_status_bar->SetStatusText("Error: Invalid buffer size.");
}
} else {
m_status_bar->SetStatusText("Ready.");
}
} else {
m_status_bar->SetStatusText("Ready.");
}
}
void MainFrame::onRunGenUpload(wxCommandEvent&)
{
if (SiggenDialog dialog (this); dialog.ShowModal() == wxID_OK) {
auto result = dialog.Result();
if (result.Find(".wav") != wxNOT_FOUND) {
// Audio
m_wav_clip = new wav::clip(result/*.Mid(1)*/);
if (m_wav_clip->valid()) {
m_status_bar->SetStatusText("Generator ready.");
} else {
delete m_wav_clip;
m_wav_clip = nullptr;
m_status_bar->SetStatusText("Error: Bad WAV file.");
}
} else if (result.find_first_not_of("0123456789 \t\r\n") == wxString::npos) {
// List
std::vector<stmdsp::dacsample_t> samples;
while (!result.IsEmpty() && samples.size() <= stmdsp::SAMPLES_MAX * 2) {
if (auto number_end = result.find_first_not_of("0123456789");
number_end != wxString::npos && number_end > 0)
{
auto number = result.Left(number_end);
if (unsigned long n; number.ToULong(&n))
samples.push_back(n & 4095);
if (auto next = result.find_first_of("0123456789", number_end + 1);
next != wxString::npos)
{
result = result.Mid(next);
} else {
break;
}
} else {
break;
}
}
if (samples.size() <= stmdsp::SAMPLES_MAX * 2) {
// DAC buffer must be of even size
if ((samples.size() & 1) == 1)
samples.push_back(0);
m_device->siggen_upload(&samples[0], samples.size());
m_status_bar->SetStatusText("Generator ready.");
} else {
m_status_bar->SetStatusText(wxString::Format("Error: Too many samples (max is %u).",
stmdsp::SAMPLES_MAX * 2));
}
} else {
extern std::vector<stmdsp::dacsample_t> siggen_formula_parse(const std::string&);
auto samples = siggen_formula_parse(result.ToStdString());
if (samples.size() > 0) {
m_device->siggen_upload(&samples[0], samples.size());
m_status_bar->SetStatusText("Generator ready.");
} else {
m_status_bar->SetStatusText("Error: Bad formula.");
}
}
} else {
m_status_bar->SetStatusText("Ready.");
}
}
void MainFrame::onRunGenStart(wxCommandEvent& ce)
{
auto menuItem = dynamic_cast<wxMenuItem *>(ce.GetEventUserData());
if (menuItem->IsChecked()) {
m_device->siggen_start();
menuItem->SetItemLabel("Stop &generator");
m_status_bar->SetStatusText("Generator running.");
} else {
m_device->siggen_stop();
menuItem->SetItemLabel("Start &generator");
m_status_bar->SetStatusText("Ready.");
}
}
void MainFrame::onRunUpload(wxCommandEvent&)
{
if (auto file = compileEditorCode(); !file.IsEmpty()) {
if (wxFileInputStream file_stream (file); file_stream.IsOk()) {
auto size = file_stream.GetSize();
auto buffer = new unsigned char[size];
file_stream.ReadAll(buffer, size);
m_device->upload_filter(buffer, size);
m_status_bar->SetStatusText("Code uploaded.");
} else {
m_status_bar->SetStatusText("Couldn't load compiled code.");
}
}
}
void MainFrame::onRunUnload(wxCommandEvent&)
{
m_device->unload_filter();
m_status_bar->SetStatusText("Unloaded code.");
}
void MainFrame::onRunCompile(wxCommandEvent&)
{
compileEditorCode();
}