From 4ae6300717a10c7fa850b800f18a730aee1d3e07 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Fri, 5 Sep 2014 19:57:14 +0200 Subject: Internal code editor. Sound system. --- src/codeeditor.cc | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/codeeditor.h | 103 +++++++++++++++++++++++++++++++++ src/kaiman.cc | 13 ++++- src/luascript.cc | 99 +++++++++++++++++++++++++++++-- src/luascript.h | 14 ++++- src/mainwindow.cc | 32 ++++++++++- src/mainwindow.h | 7 ++- src/outputwindow.cc | 27 ++++++--- src/outputwindow.h | 7 ++- src/soundplayer.cc | 134 ++++++++++++++++++++++++++++++++++++++++++ src/soundplayer.h | 60 +++++++++++++++++++ 11 files changed, 636 insertions(+), 23 deletions(-) create mode 100644 src/codeeditor.cc create mode 100644 src/codeeditor.h create mode 100644 src/soundplayer.cc create mode 100644 src/soundplayer.h (limited to 'src') diff --git a/src/codeeditor.cc b/src/codeeditor.cc new file mode 100644 index 0000000..44b0e9b --- /dev/null +++ b/src/codeeditor.cc @@ -0,0 +1,163 @@ +/**************************************************************************** + ** + ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + ** Contact: http://www.qt-project.org/legal + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + ** of its contributors may be used to endorse or promote products derived + ** from this software without specific prior written permission. + ** + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include + +#include "codeeditor.h" + + +CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) +{ + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), + this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), + this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), + this, SLOT(highlightCurrentLine())); + + setStyleSheet("font: 12pt \"Courier\";"); + + updateLineNumberAreaWidth(0); + highlightCurrentLine(); +} + + + +int CodeEditor::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; + + return space; +} + + + +void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) +{ + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); +} + + + +void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) +{ + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); +} + + + +void CodeEditor::resizeEvent(QResizeEvent *e) +{ + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), + cr.height())); +} + + + +void CodeEditor::highlightCurrentLine() +{ + QList extraSelections; + + if (!isReadOnly()) { + QTextEdit::ExtraSelection selection; + + QColor lineColor = QColor(Qt::yellow).lighter(160); + + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); +} + +void CodeEditor::runningLine(int lineno) +{ + lineNumber = lineno; + repaint(); +} + +void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + QPainter painter(lineNumberArea); + painter.fillRect(event->rect(), Qt::lightGray); + + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = + (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + if(blockNumber + 1 == lineNumber) painter.setPen(Qt::green); + else painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } +} diff --git a/src/codeeditor.h b/src/codeeditor.h new file mode 100644 index 0000000..1f0274a --- /dev/null +++ b/src/codeeditor.h @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/**************************************************************************** + ** + ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). + ** Contact: http://www.qt-project.org/legal + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names + ** of its contributors may be used to endorse or promote products derived + ** from this software without specific prior written permission. + ** + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef __CODEEDITOR_H__ +#define __CODEEDITOR_H__ + +#include +#include + +class QPaintEvent; +class QResizeEvent; +class QSize; +class QWidget; + +class LineNumberArea; + +class CodeEditor : public QPlainTextEdit +{ + Q_OBJECT + + public: + CodeEditor(QWidget *parent = 0); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + +protected: + void resizeEvent(QResizeEvent *event); + +public slots: + void runningLine(int lineno); + +private slots: + void updateLineNumberAreaWidth(int newBlockCount); + void highlightCurrentLine(); + void updateLineNumberArea(const QRect &, int); + +private: + QWidget *lineNumberArea; + int lineNumber; +}; + + +class LineNumberArea : public QWidget +{ +public: + LineNumberArea(CodeEditor *editor) : QWidget(editor) { + codeEditor = editor; + } + + QSize sizeHint() const { + return QSize(codeEditor->lineNumberAreaWidth(), 0); + } + +protected: + void paintEvent(QPaintEvent *event) { + codeEditor->lineNumberAreaPaintEvent(event); + } + +private: + CodeEditor *codeEditor; +}; + +#endif/*__CODEEDITOR_H__*/ diff --git a/src/kaiman.cc b/src/kaiman.cc index 82dcfdd..75d3035 100644 --- a/src/kaiman.cc +++ b/src/kaiman.cc @@ -27,7 +27,16 @@ */ #include +#include + #include "mainwindow.h" +#include + +void __attribute__ ((constructor)) premain() +{ + printf("premain()\n"); + printf("locale: %s\n", setlocale(LC_ALL, "da_DK")); +} int main(int argc, char *argv[]) { @@ -36,10 +45,12 @@ int main(int argc, char *argv[]) return 1; } + // QLocale::setDefault(QLocale(QLocale::Danish, QLocale::Denmark)); + QApplication app(argc, argv); MainWindow wnd(argv[1]); - // wnd.show(); + wnd.showMaximized(); return app.exec(); } diff --git a/src/luascript.cc b/src/luascript.cc index df607de..ecbed53 100644 --- a/src/luascript.cc +++ b/src/luascript.cc @@ -58,9 +58,9 @@ static int _forward(lua_State *L) Pracro::T_STRING, Pracro::T_END); */ - int x = lua_tonumber(L, lua_gettop(L)); + double x = lua_tonumber(L, lua_gettop(L)); - printf("forward %d\n", x); + printf("forward %f\n", x); lua_getglobal(L, GLOBAL_POINTER); LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); @@ -82,6 +82,33 @@ static int _forward(lua_State *L) return 0; } +static int _coord(lua_State *L) +{/* + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + */ + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return 1; + } + + if(lua->lua_stop) { + printf("stopping...\n"); + lua_pushstring(L, "stop"); + lua_error(L); + } + + lua_pushnumber(L, lua->out->coordX()); + lua_pushnumber(L, lua->out->coordY()); + + return 2; +} + static int _loadpen(lua_State *L) {/* Pracro::checkParameters(L, @@ -211,9 +238,9 @@ static int _turn(lua_State *L) Pracro::T_STRING, Pracro::T_END); */ - int x = lua_tonumber(L, lua_gettop(L)); + double x = lua_tonumber(L, lua_gettop(L)); - printf("turn %d\n", x); + printf("turn %f\n", x); lua_getglobal(L, GLOBAL_POINTER); LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); @@ -235,6 +262,22 @@ static int _turn(lua_State *L) return 0; } +static int _playsound(lua_State *L) +{/* + Pracro::checkParameters(L, + Pracro::T_STRING, + Pracro::T_END); + */ + QString file = lua_tostring(L, lua_gettop(L)); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + lua->playSound(file); + + return 0; +} + static int _reset(lua_State *L) {/* Pracro::checkParameters(L, @@ -263,6 +306,36 @@ static int _reset(lua_State *L) return 0; } +void hook(lua_State *L, lua_Debug *ar) +{ + lua_getinfo(L, "Snl", ar); + + lua_getglobal(L, GLOBAL_POINTER); + LUAScript *lua = (LUAScript*)lua_touserdata(L, lua_gettop(L)); + + if(!lua) { + lua_pushstring(L, "No LUA pointer!"); + lua_error(L); + return; + } + + // printf("kaiman file: %s\n", lua->file.toStdString().c_str()); + + if(lua->file == QString(ar->short_src)) { + // printf(" ---- currentline: %d\n", ar->currentline); + lua->lineChange(ar->currentline); + qApp->processEvents(); + } + /* + printf("HOOK:\n"); + printf(" what: %s\n", ar->what); + printf(" name: %s\n", ar->name); + printf(" source: %s\n", ar->source); + printf(" short_src: %s\n", ar->short_src); + printf(" currentline: %d\n", ar->currentline); + */ +} + LUAScript::LUAScript(OutputWindow *o, QString f) { DEBUG(luascript, "LUAScript()\n"); @@ -281,6 +354,11 @@ LUAScript::~LUAScript() DEBUG(luascript, "~LUAScript()\n"); } +void LUAScript::lineChange(int lineno) +{ + emit lineChanged(lineno); +} + void LUAScript::init() throw(Exception) { @@ -298,13 +376,17 @@ void LUAScript::init() lua_setglobal(L, GLOBAL_POINTER); // Assign it to a global lua var. lua_register(L, "debug", _debug); - lua_register(L, "fremad", _forward); - lua_register(L, "drej", _turn); + lua_register(L, "forward", _forward); + lua_register(L, "turn", _turn); lua_register(L, "speed", _speed); lua_register(L, "scale", _scale); lua_register(L, "reset", _reset); lua_register(L, "colour", _colour); lua_register(L, "loadpen", _loadpen); + lua_register(L, "coord", _coord); + lua_register(L, "playsound", _playsound); + + lua_sethook(L, hook, LUA_MASKLINE, 0); } void LUAScript::cleanup() @@ -329,6 +411,11 @@ void LUAScript::run() printf("LUA Thread Stopped!\n"); } +void LUAScript::playSound(QString file) +{ + player.playFile(file); +} + void LUAScript::stopScript() { lua_stop = true; diff --git a/src/luascript.h b/src/luascript.h index 6516611..93478df 100644 --- a/src/luascript.h +++ b/src/luascript.h @@ -36,6 +36,7 @@ #include #include "outputwindow.h" +#include "soundplayer.h" #include @@ -59,13 +60,20 @@ public: OutputWindow *out; - void stopScript(); + void lineChange(int lineno); + + void playSound(QString file); volatile bool lua_stop; volatile bool lua_stopped; + QString file; + +public slots: + void stopScript(); signals: void reset(); + void lineChanged(int lineno); protected: lua_State *L; @@ -76,9 +84,9 @@ private: int top; - QString file; - bool running; + + SoundPlayer player; }; diff --git a/src/mainwindow.cc b/src/mainwindow.cc index c8036ca..ba6c779 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -30,20 +30,45 @@ #include "outputwindow.h" #include +#include +#include +#include +#include MainWindow::MainWindow(QString p) { program = p; + /* // Watch file on disk? connect(&watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(reset())); watcher.addPath(program); + */ + QSplitter *splitter = new QSplitter(); + setCentralWidget(splitter); + + editor = new CodeEditor(); + splitter->addWidget(editor); + QFile file(program); + file.open(QIODevice::ReadOnly); + editor->setPlainText(file.readAll()); + file.close(); + out = new OutputWindow(); - out->show(); + splitter->addWidget(out); l = new LUAScript(out, program); + connect(l, SIGNAL(lineChanged(int)), editor, SLOT(runningLine(int))); + + QToolBar *toolbar = new QToolBar(); + addToolBar(Qt::TopToolBarArea, toolbar); + QAction *act_run = toolbar->addAction("Run"); + connect(act_run, SIGNAL(triggered()), this, SLOT(reset())); + + QAction *act_stop = toolbar->addAction("Stop"); + connect(act_stop, SIGNAL(triggered()), l, SLOT(stopScript())); reset(); } @@ -51,6 +76,11 @@ MainWindow::MainWindow(QString p) void MainWindow::reset() { printf("Resetting...\n"); + QFile file(program); + file.open(QIODevice::WriteOnly); + QString code = editor->toPlainText(); + file.write(code.toStdString().c_str(), code.length()); + file.close(); out->stopScript(); l->stopScript(); out->reset(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 1376a84..c9a1844 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -28,14 +28,15 @@ #ifndef __KAIMAN_MAINWINDOW_H__ #define __KAIMAN_MAINWINDOW_H__ -#include +#include #include +#include "codeeditor.h" #include "outputwindow.h" #include "luascript.h" -class MainWindow : public QWidget { +class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QString program); @@ -44,6 +45,8 @@ private slots: void reset(); private: + CodeEditor *editor; + QFileSystemWatcher watcher; QString program; OutputWindow *out; diff --git a/src/outputwindow.cc b/src/outputwindow.cc index 43e691f..498af23 100644 --- a/src/outputwindow.cc +++ b/src/outputwindow.cc @@ -48,6 +48,16 @@ OutputWindow::OutputWindow() reset(); } +double OutputWindow::coordX() +{ + return x; +} + +double OutputWindow::coordY() +{ + return y; +} + void OutputWindow::stopScript() { stop = true; @@ -117,7 +127,7 @@ void OutputWindow::paintEvent(QPaintEvent *) p.setTransform(gt); QPen pen; - pen.setWidth(6); + pen.setWidth(4); /* p.setPen(pen); p.drawLines(points); @@ -148,7 +158,7 @@ void OutputWindow::paintEvent(QPaintEvent *) QColor c = colour; c.setAlpha(c.alpha() / 4); pen.setStyle(Qt::SolidLine); - pen.setWidth(6); + pen.setWidth(4); pen.setColor(c); p.setPen(pen); for(int i = 0; i < current_points.size(); i+=2) { @@ -183,9 +193,10 @@ static inline int sign(int x) return -1; } -void OutputWindow::forward(int dist) +void OutputWindow::forward(double dist) { sem.acquire(); + float target_x = sin(r * (M_PI / 180.0)) * dist; float target_y = cos(r * (M_PI / 180.0)) * dist; @@ -222,15 +233,15 @@ void OutputWindow::forward(int dist) } // Turn x degrees -void OutputWindow::turn(int x) +void OutputWindow::turn(double x) { - int spd = (speed * abs(x) / 80); - float offset = this->r; + double spd = (speed * abs(x) / 80.0); + double offset = this->r; sem.acquire(); for(int i = 0; i < spd; i++) { if(stop) return; - float p = (float)i / (float)spd; - this->r = offset + (float)x * p; + double p = (double)i / spd; + this->r = offset + x * p; sem.acquire(); } this->r = offset + x; diff --git a/src/outputwindow.h b/src/outputwindow.h index d875b36..bd8bf27 100644 --- a/src/outputwindow.h +++ b/src/outputwindow.h @@ -40,8 +40,8 @@ Q_OBJECT public: OutputWindow(); - void forward(int x); - void turn(int x); + void forward(double x); + void turn(double x); void stopScript(); @@ -51,6 +51,9 @@ public: void loadPen(QString file); + double coordX(); + double coordY(); + public slots: void timeout(); void reset(); diff --git a/src/soundplayer.cc b/src/soundplayer.cc new file mode 100644 index 0000000..c59e84e --- /dev/null +++ b/src/soundplayer.cc @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * soundplayer.cc + * + * Fri Sep 5 17:31:28 CEST 2014 + * Copyright 2014 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Kaiman. + * + * Kaiman 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. + * + * Kaiman 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 Kaiman; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "soundplayer.h" + +#include +#include + +#define BUFSZ 512 + +SoundPlayer::SoundPlayer() +{ + start(); +} + +SoundPlayer::~SoundPlayer() +{ + running = false; + wait(); +} + +void SoundPlayer::run() +{ + + printf("SoundPlayer running\n"); + + ao_initialize(); + + ao_sample_format sf; + memset(&sf, 0, sizeof(sf)); + sf.bits = 16; + sf.rate = 44100; + sf.channels = 2; + sf.byte_format = AO_FMT_NATIVE; + + ao_device *dev = ao_open_live(ao_default_driver_id(), &sf, 0); + + running = true; + + short s[BUFSZ]; + while(running) { + + { // Check for new Selection. + QMutexLocker lock(&mutex); + while(queue.size()) { + printf(" - New sound\n"); + active.append(queue.front()); + queue.pop_front(); + } + } + + memset(s, 0, BUFSZ * sizeof(short)); + + QList::iterator it = active.begin(); + while(it != active.end()) { + QueueItem &item = *it; + + for(size_t i = 0; i < BUFSZ; i++) { + if(item.pos >= item.size) { + it = active.erase(it); + goto nextitem; + } + s[i] += item.samples[item.pos] * 32536; + item.pos++; + } + + it++; + + nextitem: + int a = 1;(void)a; + } + + ao_play(dev, (char*)s, BUFSZ * sizeof(short)); + } + + ao_close(dev); + ao_shutdown(); +} + +void SoundPlayer::playFile(QString file) +{ + + printf(" - playFile(%s)\n", file.toStdString().c_str()); + + SNDFILE *fh; + SF_INFO sf_info; + + fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info); + if(!fh) { + printf("Load error '%s'\n", file.toStdString().c_str()); + return; + } + + size_t size = sf_info.frames * sf_info.channels; + float *data = new float[size]; + sf_read_float(fh, data, size); + + sf_close(fh); + + QueueItem qi; + qi.samples = data; + qi.pos = 0; + qi.size = size; + + { + QMutexLocker lock(&mutex); + queue.append(qi); + } + +} diff --git a/src/soundplayer.h b/src/soundplayer.h new file mode 100644 index 0000000..c5b36d4 --- /dev/null +++ b/src/soundplayer.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * soundplayer.h + * + * Fri Sep 5 17:31:27 CEST 2014 + * Copyright 2014 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Kaiman. + * + * Kaiman 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. + * + * Kaiman 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 Kaiman; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __KAIMAN_SOUNDPLAYER_H__ +#define __KAIMAN_SOUNDPLAYER_H__ + +#include +#include +#include +#include + +class QueueItem { +public: + float *samples; + size_t pos; + size_t size; +}; + +class SoundPlayer : public QThread { +public: + SoundPlayer(); + ~SoundPlayer(); + + void playFile(QString file); + + void run(); + +private: + volatile bool running; + QMutex mutex; + + QList queue; + QList active; +}; + +#endif/*__KAIMAN_SOUNDPLAYER_H__*/ -- cgit v1.2.3