From 68e4647e565519c57d76b95806dd9431a4ecfbb1 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Fri, 18 Apr 2014 13:16:03 +0200 Subject: New player model (again). --- dgedit/player.cc | 104 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 21 deletions(-) (limited to 'dgedit/player.cc') diff --git a/dgedit/player.cc b/dgedit/player.cc index baaf975..745052e 100644 --- a/dgedit/player.cc +++ b/dgedit/player.cc @@ -28,17 +28,17 @@ #include -#define BUFSZ 1024 * 2 +#define BUFSZ 512 Player::Player() { - playing = false; - 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 @@ -52,8 +52,11 @@ Player::~Player() wait(); // Wait for player thread to stop. } +#define _MIN(a, b) (a peak) peak = abs(sample); - s[i] = sample * SHRT_MAX; + + { // Check for new Selection. + QMutexLocker lock(&mutex); + if(new_selection) { + sel = selection; + pos = sel.from; + end = sel_end; + new_selection = false; } + } - ao_play(dev, (char*)s, BUFSZ * sizeof(short)); + for(size_t i = 0; i < BUFSZ; i++) { + double sample = 0.0; + size_t p = i + pos; + if(p < sel.to && p < end && p < pcm_size) { + double fade = 1; + if(p < (sel.from + sel.fadein)) { + // Apply linear fade-in + double fp = p - sel.from; + fade = fp / (double)sel.fadeout; + } - pos += BUFSZ; + if(p > (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); + } - } else { - msleep(22); + sample = pcm_data[p] * fade * gain_scalar; + } + if(abs(sample) > peak) peak = abs(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; @@ -120,7 +167,22 @@ void Player::setPcmData(float *data, size_t size) pcm_size = size; } - void Player::setPosition(size_t position) - { - pos = position; - } +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