mirror of https://github.com/odrling/Aegisub
Preparations for audio scrubbing
Originally committed to SVN as r459.
This commit is contained in:
parent
721d7860d6
commit
41a4cd3c2c
|
@ -97,6 +97,10 @@ private:
|
||||||
int *peak;
|
int *peak;
|
||||||
int *min;
|
int *min;
|
||||||
|
|
||||||
|
int scrubTime;
|
||||||
|
int scrubLastPos;
|
||||||
|
bool scrubbing;
|
||||||
|
|
||||||
void OnPaint(wxPaintEvent &event);
|
void OnPaint(wxPaintEvent &event);
|
||||||
void OnMouseEvent(wxMouseEvent &event);
|
void OnMouseEvent(wxMouseEvent &event);
|
||||||
void OnSize(wxSizeEvent &event);
|
void OnSize(wxSizeEvent &event);
|
||||||
|
@ -115,6 +119,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioProvider *provider;
|
AudioProvider *provider;
|
||||||
|
AudioProvider *scrubProvider;
|
||||||
AudioPlayer *player;
|
AudioPlayer *player;
|
||||||
|
|
||||||
bool NeedCommit;
|
bool NeedCommit;
|
||||||
|
|
|
@ -107,11 +107,6 @@ int PortAudioPlayer::paCallback(void *inputBuffer, void *outputBuffer, unsigned
|
||||||
provider->GetAudio(outputBuffer,player->playPos,lenAvailable);
|
provider->GetAudio(outputBuffer,player->playPos,lenAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad end with blank
|
|
||||||
if (avail < (uint64_t) framesPerBuffer) {
|
|
||||||
//provider->softStop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set volume
|
// Set volume
|
||||||
short *output = (short*) outputBuffer;
|
short *output = (short*) outputBuffer;
|
||||||
for (unsigned int i=0;i<avail;i++) output[i] = MID(-(1<<15),int(output[i] * player->GetVolume()),(1<<15)-1);
|
for (unsigned int i=0;i<avail;i++) output[i] = MID(-(1<<15),int(output[i] * player->GetVolume()),(1<<15)-1);
|
||||||
|
|
|
@ -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<BufferChunk*>::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<count;i++) {
|
||||||
|
dst[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// Append audio to stream
|
||||||
|
void StreamAudioProvider::Append(void *src, __int64 count) {
|
||||||
|
// Read
|
||||||
|
__int64 left = count;
|
||||||
|
__int64 read = 0;
|
||||||
|
int toRead;
|
||||||
|
while (left > 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;
|
||||||
|
}
|
|
@ -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 <list>
|
||||||
|
#include <vector>
|
||||||
|
#include "audio_provider.h"
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// Audio provider class
|
||||||
|
class StreamAudioProvider : public AudioProvider {
|
||||||
|
private:
|
||||||
|
// Buffer chunk subclass
|
||||||
|
class BufferChunk {
|
||||||
|
public:
|
||||||
|
std::vector<short> buf;
|
||||||
|
bool isFree;
|
||||||
|
BufferChunk();
|
||||||
|
};
|
||||||
|
|
||||||
|
std::list<BufferChunk*> buffer;
|
||||||
|
int startPos;
|
||||||
|
int endPos;
|
||||||
|
int bufLen;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StreamAudioProvider();
|
||||||
|
~StreamAudioProvider();
|
||||||
|
|
||||||
|
void GetAudio(void *buf, __int64 start, __int64 count);
|
||||||
|
void Append(void *buf, __int64 count);
|
||||||
|
};
|
Loading…
Reference in New Issue