Skip to content

Commit

Permalink
MIDI file playback using Sonivox library
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrolcl committed Apr 30, 2016
1 parent 7691d33 commit 7e87429
Show file tree
Hide file tree
Showing 15 changed files with 479 additions and 32 deletions.
9 changes: 8 additions & 1 deletion cmdlnsynth/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,16 @@ int main(int argc, char *argv[])
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
synth = new SynthController();
QObject::connect(synth, &SynthController::finished, &app, &QCoreApplication::quit);
QObject::connect(synth->renderer(), &SynthRenderer::playbackStopped, &app, &QCoreApplication::quit);
QObject::connect(&app, &QCoreApplication::aboutToQuit, synth, &QObject::deleteLater);
synth->renderer()->initReverb(EAS_PARAM_REVERB_HALL);
QStringList args = app.arguments();
for(int i = 1; i < args.length(); ++i) {
QFile argFile(args[i]);
if (argFile.exists()) {
synth->renderer()->playFile(argFile.fileName());
}
}
synth->start();
return app.exec();
}
3 changes: 3 additions & 0 deletions guisynth/guisynth.qrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<RCC>
<qresource prefix="/">
<file>icon.png</file>
<file>open.png</file>
<file>play.png</file>
<file>stop.png</file>
</qresource>
</RCC>
82 changes: 81 additions & 1 deletion guisynth/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
*/

#include <QCloseEvent>
#include <QFileDialog>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_synth(new SynthController(this))
m_synth(new SynthController(this)),
m_state(InitialState)
{
ui->setupUi(this);
ui->combo_Reverb->addItem(QStringLiteral("Large Hall"), 0);
Expand All @@ -45,9 +47,16 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->combo_Chorus, SIGNAL(currentIndexChanged(int)), SLOT(chorusTypeChanged(int)));
connect(ui->dial_Reverb, &QDial::valueChanged, this, &MainWindow::reverbChanged);
connect(ui->dial_Chorus, &QDial::valueChanged, this, &MainWindow::chorusChanged);
connect(ui->openButton, &QToolButton::clicked, this, &MainWindow::openFile);
connect(ui->playButton, &QToolButton::clicked, this, &MainWindow::playSong);
connect(ui->stopButton, &QToolButton::clicked, this, &MainWindow::stopSong);
connect(m_synth->renderer(), &SynthRenderer::playbackStopped, this, &MainWindow::songStopped);

ui->combo_Reverb->setCurrentIndex(1);
ui->dial_Reverb->setValue(25800);

m_songFile = QString();
updateState(EmptyState);
}

MainWindow::~MainWindow()
Expand Down Expand Up @@ -100,3 +109,74 @@ MainWindow::chorusChanged(int value)
{
m_synth->renderer()->setChorusLevel(value);
}

void
MainWindow::openFile()
{
m_songFile = QFileDialog::getOpenFileName(this,
tr("Open MIDI file"), QDir::homePath(),
tr("MIDI Files (*.mid *.midi *.kar)"));
if (m_songFile.isEmpty()) {
ui->lblSong->setText("[empty]");
updateState(EmptyState);
} else {
QFileInfo f(m_songFile);
ui->lblSong->setText(f.fileName());
updateState(StoppedState);
}
}

void
MainWindow::playSong()
{
if (m_state == StoppedState) {
m_synth->renderer()->startPlayback(m_songFile);
updateState(PlayingState);
}
}

void
MainWindow::stopSong()
{
if (m_state == PlayingState) {
m_synth->renderer()->stopPlayback();
updateState(StoppedState);
}
}

void
MainWindow::songStopped()
{
if (m_state != StoppedState) {
updateState(StoppedState);
}
}

void
MainWindow::updateState(PlayerState newState)
{
//qDebug() << Q_FUNC_INFO << newState;
if (m_state != newState) {
switch (newState) {
case EmptyState:
ui->playButton->setEnabled(false);
ui->stopButton->setEnabled(false);
ui->openButton->setEnabled(true);
break;
case PlayingState:
ui->playButton->setEnabled(false);
ui->stopButton->setEnabled(true);
ui->openButton->setEnabled(false);
break;
case StoppedState:
ui->stopButton->setEnabled(true);
ui->playButton->setEnabled(true);
ui->playButton->setChecked(false);
ui->openButton->setEnabled(true);
break;
default:
break;
}
m_state = newState;
}
}
15 changes: 15 additions & 0 deletions guisynth/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
#include <QMainWindow>
#include "synthcontroller.h"

enum PlayerState {
InitialState,
EmptyState,
PlayingState,
StoppedState
};

namespace Ui {
class MainWindow;
}
Expand All @@ -34,6 +41,7 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void updateState(PlayerState newState);

protected:
virtual void showEvent(QShowEvent *ev);
Expand All @@ -44,10 +52,17 @@ private slots:
void chorusTypeChanged(int index);
void reverbChanged(int value);
void chorusChanged(int value);
void songStopped();

void openFile();
void playSong();
void stopSong();

private:
Ui::MainWindow *ui;
SynthController *m_synth;
QString m_songFile;
PlayerState m_state;
};

#endif // MAINWINDOW_H
82 changes: 74 additions & 8 deletions guisynth/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>250</width>
<height>167</height>
<width>190</width>
<height>208</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -19,7 +19,73 @@
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<item row="0" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="playButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="guisynth.qrc">
<normaloff>:/play.png</normaloff>:/play.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="stopButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="guisynth.qrc">
<normaloff>:/stop.png</normaloff>:/stop.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="openButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="guisynth.qrc">
<normaloff>:/open.png</normaloff>:/open.png</iconset>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblSong">
<property name="text">
<string>[empty]</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>8</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblReverb">
<property name="text">
<string>Reverb</string>
Expand All @@ -29,7 +95,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="2" column="2">
<widget class="QLabel" name="lblChorus">
<property name="text">
<string>Chorus</string>
Expand All @@ -39,24 +105,24 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="3" column="0" colspan="2">
<widget class="QDial" name="dial_Reverb">
<property name="maximum">
<number>32765</number>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="3" column="2">
<widget class="QDial" name="dial_Chorus">
<property name="maximum">
<number>32765</number>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="4" column="0" colspan="2">
<widget class="QComboBox" name="combo_Reverb"/>
</item>
<item row="2" column="1">
<item row="4" column="2">
<widget class="QComboBox" name="combo_Chorus"/>
</item>
</layout>
Expand Down
Binary file added guisynth/open.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added guisynth/play.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added guisynth/stop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions libsvoxeas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ link_directories(
set( HEADERS
synthcontroller.h
synthrenderer.h
)
filewrapper.h
)

set( SOURCES
synthcontroller.cpp
synthrenderer.cpp
)
filewrapper.cpp
)

qt5_wrap_cpp( MOC_SRCS ${HEADERS} )

Expand Down
78 changes: 78 additions & 0 deletions libsvoxeas/filewrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
Sonivox EAS Synthesizer for Qt applications
Copyright (C) 2016, Pedro Lopez-Cabanillas <[email protected]>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include <QDebug>
#include "filewrapper.h"

static int
readAt(void *handle, void *buffer, int pos, int size) {
return ((FileWrapper*)handle)->readAt(buffer, pos, size);
}

static int
size(void *handle) {
return ((FileWrapper*)handle)->size();
}

FileWrapper::FileWrapper(const QString path)
{
//qDebug() << Q_FUNC_INFO << path;
m_file = new QFile(path);
m_file->open(QIODevice::ReadOnly);
m_Base = 0;
m_Length = m_file->size();
}

FileWrapper::FileWrapper(const char *path)
{
//qDebug("FileWrapper(path=%s)", path);
m_file = new QFile(path);
m_file->open(QIODevice::ReadOnly);
m_Base = 0;
m_Length = m_file->size();
}

FileWrapper::~FileWrapper() {
//qDebug("~FileWrapper");
m_file->close();
}

int
FileWrapper::readAt(void *buffer, int offset, int size) {
//qDebug("readAt(%p, %d, %d)", buffer, offset, size);
m_file->seek(offset);
if (offset + size > m_Length) {
size = m_Length - offset;
}
return m_file->read((char *)buffer, size);
}

int
FileWrapper::size() {
//qDebug("size() = %d", int(mLength));
return m_Length;
}

EAS_FILE_LOCATOR
FileWrapper::getLocator() {
m_easFile.handle = this;
m_easFile.readAt = ::readAt;
m_easFile.size = ::size;
return &m_easFile;
}
Loading

0 comments on commit 7e87429

Please sign in to comment.