From 41a4cd3c2c36cff0a7c50f91a184d6bca4be6c44 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Tue, 4 Jul 2006 05:10:29 +0000 Subject: [PATCH] Preparations for audio scrubbing Originally committed to SVN as r459. --- core/audio_display.h | 5 ++ core/audio_player_portaudio.cpp | 5 -- core/audio_provider_stream.cpp | 131 ++++++++++++++++++++++++++++++++ core/audio_provider_stream.h | 70 +++++++++++++++++ 4 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 core/audio_provider_stream.cpp create mode 100644 core/audio_provider_stream.h diff --git a/core/audio_display.h b/core/audio_display.h index cf05deaa0..23b3d3a99 100644 --- a/core/audio_display.h +++ b/core/audio_display.h @@ -97,6 +97,10 @@ private: int *peak; int *min; + int scrubTime; + int scrubLastPos; + bool scrubbing; + void OnPaint(wxPaintEvent &event); void OnMouseEvent(wxMouseEvent &event); void OnSize(wxSizeEvent &event); @@ -115,6 +119,7 @@ private: public: AudioProvider *provider; + AudioProvider *scrubProvider; AudioPlayer *player; bool NeedCommit; diff --git a/core/audio_player_portaudio.cpp b/core/audio_player_portaudio.cpp index 47744d91b..cf7dfd025 100644 --- a/core/audio_player_portaudio.cpp +++ b/core/audio_player_portaudio.cpp @@ -107,11 +107,6 @@ int PortAudioPlayer::paCallback(void *inputBuffer, void *outputBuffer, unsigned provider->GetAudio(outputBuffer,player->playPos,lenAvailable); } - // Pad end with blank - if (avail < (uint64_t) framesPerBuffer) { - //provider->softStop = true; - } - // Set volume short *output = (short*) outputBuffer; for (unsigned int i=0;iGetVolume()),(1<<15)-1); diff --git a/core/audio_provider_stream.cpp b/core/audio_provider_stream.cpp new file mode 100644 index 000000000..cedda688d --- /dev/null +++ b/core/audio_provider_stream.cpp @@ -0,0 +1,131 @@ +// Copyright (c) 2006, Rodrigo Braz Monteiro +// All rights reserved. +// +// 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 the Aegisub Group 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. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + + +/////////// +// Headers +#include "audio_provider_stream.h" +#include "utils.h" + + +/////////////// +// Constructor +StreamAudioProvider::StreamAudioProvider() { + bufLen = 8192; + startPos = 0; + endPos = 8192; +} + + +////////////// +// Destructor +StreamAudioProvider::~StreamAudioProvider() { + for (std::list::iterator cur=buffer.begin();cur!=buffer.end();cur++) { + delete *cur; + } + buffer.clear(); +} + + +///////////// +// Get audio +void StreamAudioProvider::GetAudio(void *buf, __int64 start, __int64 count) { + // Write + __int64 left = count; + __int64 written = 0; + int toWrite; + while (left > 0) { + // Discard done + if (startPos == 8192) { + buffer.pop_front(); + startPos = 0; + } + + // Is last? + bool isLast = buffer.size() == 1; + int size = 8192; + if (isLast) size = endPos; + + // Write + toWrite = MIN(int(size-startPos),int(left)); + memcpy(((short*)buf)+written,&(buffer.front()->buf[startPos]),toWrite); + startPos += toWrite; + written += toWrite; + left -= toWrite; + + // Last + if (isLast) break; + } + + // Still left, fill with zero + if (left > 0) { + short *dst = (short*) buf; + for (__int64 i=written;i 0) { + // Check space + if (endPos == 8192) { + buffer.push_back(new BufferChunk); + endPos = 0; + } + + // Read + toRead = MIN(int(8192-endPos),int(left)); + memcpy(&(buffer.back()->buf[endPos]),((short*)src)+read,toRead); + endPos += toRead; + read += toRead; + left -= toRead; + } +} + + +//////////////////////////// +// Buffer chunk constructor +StreamAudioProvider::BufferChunk::BufferChunk() { + buf.resize(4096); + isFree = true; +} diff --git a/core/audio_provider_stream.h b/core/audio_provider_stream.h new file mode 100644 index 000000000..bfca0208c --- /dev/null +++ b/core/audio_provider_stream.h @@ -0,0 +1,70 @@ +// Copyright (c) 2006, Rodrigo Braz Monteiro +// All rights reserved. +// +// 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 the Aegisub Group 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. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + + +#pragma once + + +/////////// +// Headers +#include +#include +#include "audio_provider.h" + + +//////////////////////// +// Audio provider class +class StreamAudioProvider : public AudioProvider { +private: + // Buffer chunk subclass + class BufferChunk { + public: + std::vector buf; + bool isFree; + BufferChunk(); + }; + + std::list buffer; + int startPos; + int endPos; + int bufLen; + +public: + StreamAudioProvider(); + ~StreamAudioProvider(); + + void GetAudio(void *buf, __int64 start, __int64 count); + void Append(void *buf, __int64 count); +};