From 7776aa97fc1c69a8f28ba4bab7387fb96be9a6e4 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 8 Sep 2014 20:48:38 +0200 Subject: Import dgedit from drumgizmo repository (split into its own project). --- src/player.cc | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/player.cc (limited to 'src/player.cc') diff --git a/src/player.cc b/src/player.cc new file mode 100644 index 0000000..3a2bfd2 --- /dev/null +++ b/src/player.cc @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * player.cc + * + * Tue Apr 15 10:34:18 CEST 2014 + * Copyright 2014 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo 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. + * + * DrumGizmo 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 DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "player.h" + +#include + +#define BUFSZ 512 + +Player::Player() +{ + peak = 0; + pos = 0; + gain_scalar = 1.0; + pcm_data = NULL; + pcm_size = 0; + end = 0; + new_selection = false; + + connect(&report_timer, SIGNAL(timeout()), this, SLOT(reportTimeout())); + report_timer.start(50); // Update 25 times per second + + start(); +} + +Player::~Player() +{ + running = false; // Signal player thread to stop + wait(); // Wait for player thread to stop. +} + +#define _MIN(a, b) (a (sel.to - sel.fadeout)) { + // Apply linear fade-out + double fp = (double)(((int)sel.to - (int)sel.fadeout) - (int)p); + fade = 1 + (fp / (double)sel.fadeout); + } + + sample = pcm_data[p] * fade * gain_scalar; + } + if(fabs(sample) > peak) { + peak = fabs(sample); + } + s[i] = _MIN(sample * SHRT_MAX, SHRT_MAX); + } + + ao_play(dev, (char*)s, BUFSZ * sizeof(short)); + + pos += BUFSZ; + } + + ao_close(dev); + ao_shutdown(); +} + +bool Player::playSelectionDone() +{ + return pos >= sel_end || pos >= selection.to; +} + +void Player::playSelection(Selection s, int len) +{ + { // Enqueue new Selection for player consumation + QMutexLocker lock(&mutex); + + selection = s; + + if(len > 0) sel_end = len; + else sel_end = selection.to - selection.from; + + sel_end += selection.from; + + new_selection = true; + } + + // Wait until player actually consumed the new Selection. + while(new_selection) { + msleep(1); + } +} + +void Player::setGainScalar(double g) +{ + gain_scalar = g; +} + +void Player::setGainDB(double gain_db) +{ + setGainScalar(pow(10, gain_db/ 20.0)); +} + +void Player::reportTimeout() +{ + emit peakUpdate(peak); + emit peakUpdateDB(20 * log10(peak)); + peak = 0.0; + + emit positionUpdate(pos); + peak = 0.0; +} + +void Player::setPcmData(float *data, size_t size) +{ + pcm_data = data; + pcm_size = size; +} + +void Player::setPosition(size_t position) +{ + Selection s; + s.from = position; + s.to = pcm_size; + s.fadein = 0; + s.fadeout = 0; + playSelection(s); +} + +void Player::stop() +{ + Selection s; + s.from = 0; + s.to = 0; + s.fadein = 0; + s.fadeout = 0; + playSelection(s, pos); +} -- cgit v1.2.3