From 4e464c97adb44ba2978f578c2abba1740045ccad Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Tue, 4 Jul 2006 06:13:54 +0000 Subject: [PATCH] Quite broken scrubbing implemented Originally committed to SVN as r460. --- core/audio_display.cpp | 83 +++++++++++++++++++++++++++++++++- core/audio_display.h | 5 +- core/audio_provider_stream.cpp | 12 ++++- core/audio_provider_stream.h | 1 + 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/core/audio_display.cpp b/core/audio_display.cpp index d44de8cd6..d1ea9f013 100644 --- a/core/audio_display.cpp +++ b/core/audio_display.cpp @@ -38,6 +38,7 @@ // Headers #include #include "audio_display.h" +#include "audio_provider_stream.h" #include "main.h" #include "ass_dialogue.h" #include "subs_grid.h" @@ -77,6 +78,7 @@ AudioDisplay::AudioDisplay(wxWindow *parent,VideoDisplay *display) dontReadTimes = false; holding = false; draggingScale = false; + scrubbing = false; Position = 0; PositionSample = 0; oldCurPos = 0; @@ -1195,7 +1197,86 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) { } if (!event.ButtonIsDown(wxMOUSE_BTN_LEFT) && holding) { holding = false; - ReleaseMouse(); + if (HasCapture()) ReleaseMouse(); + } + + // Stop scrubbing + bool scrubButton = event.ButtonIsDown(wxMOUSE_BTN_MIDDLE); + if (scrubbing && !scrubButton) { + // Release mouse + scrubbing = false; + if (HasCapture()) ReleaseMouse(); + + // Stop player + player->Stop(); + player->SetProvider(provider); + delete scrubProvider; + } + + // Start scrubbing + if (!scrubbing && scrubButton) { + // Get mouse + CaptureMouse(); + scrubbing = true; + + // Initialize provider + player->Stop(); + scrubProvider = new StreamAudioProvider(); + scrubProvider->SetParams(provider->GetChannels(),provider->GetSampleRate(),provider->GetBytesPerSample()); + player->SetProvider(scrubProvider); + + // Set variables + scrubLastPos = GetSampleAtX(x); + scrubTime = clock(); + } + + // Scrub + if (scrubbing && scrubButton) { + // Get current data + __int64 curScrubPos = GetSampleAtX(x); + __int64 scrubDelta = scrubLastPos - curScrubPos; + int curScrubTime = clock(); + int scrubDeltaTime = curScrubTime - scrubTime; + + // Copy data to buffer + if (scrubDelta != 0 && scrubDeltaTime > 0) { + // Create buffer + int bufSize = scrubDeltaTime * scrubProvider->GetSampleRate() / CLK_TCK; + short *buf = new short[bufSize]; + + // Flag as inverted, if necessary + bool invert = scrubDelta < 0; + if (invert) scrubDelta = -scrubDelta; + + // Copy data from original provider to buffer and normalize it + short *temp = new short[scrubDelta]; + provider->GetAudio(temp,MIN(curScrubPos,scrubLastPos),scrubDelta); + float scale = float(scrubDelta) / float(bufSize); + for (int i=0;iAppend(buf,bufSize); + if (!player->IsPlaying()) player->Play(0,0xFFFFFFFFFFFF); + delete buf; + } + + // Update last pos and time + scrubLastPos = curScrubPos; + scrubTime = curScrubTime; + + // Return + return; } // Mouse wheel diff --git a/core/audio_display.h b/core/audio_display.h index 23b3d3a99..df9154d08 100644 --- a/core/audio_display.h +++ b/core/audio_display.h @@ -48,6 +48,7 @@ ////////////// // Prototypes class AssDialogue; +class StreamAudioProvider; class SubtitlesGrid; class AudioBox; class AudioKaraoke; @@ -98,7 +99,7 @@ private: int *min; int scrubTime; - int scrubLastPos; + __int64 scrubLastPos; bool scrubbing; void OnPaint(wxPaintEvent &event); @@ -119,7 +120,7 @@ private: public: AudioProvider *provider; - AudioProvider *scrubProvider; + StreamAudioProvider *scrubProvider; AudioPlayer *player; bool NeedCommit; diff --git a/core/audio_provider_stream.cpp b/core/audio_provider_stream.cpp index cedda688d..d44be4bfc 100644 --- a/core/audio_provider_stream.cpp +++ b/core/audio_provider_stream.cpp @@ -46,6 +46,7 @@ StreamAudioProvider::StreamAudioProvider() { bufLen = 8192; startPos = 0; endPos = 8192; + num_samples = 0xFFFFFFFFFFFFFF; } @@ -123,9 +124,18 @@ void StreamAudioProvider::Append(void *src, __int64 count) { } +////////////////// +// Set parameters +void StreamAudioProvider::SetParams(int chan,int rate,int bps) { + channels = chan; + sample_rate = rate; + bytes_per_sample = bps; +} + + //////////////////////////// // Buffer chunk constructor StreamAudioProvider::BufferChunk::BufferChunk() { - buf.resize(4096); + buf.resize(8192); isFree = true; } diff --git a/core/audio_provider_stream.h b/core/audio_provider_stream.h index bfca0208c..648ad9507 100644 --- a/core/audio_provider_stream.h +++ b/core/audio_provider_stream.h @@ -67,4 +67,5 @@ public: void GetAudio(void *buf, __int64 start, __int64 count); void Append(void *buf, __int64 count); + void SetParams(int channels,int rate,int bps); };