summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorUwe Klotz <uwe_klotz@web.de>2017-07-30 16:31:57 +0200
committerUwe Klotz <uwe_klotz@web.de>2017-11-06 22:27:20 +0100
commit36c51de0a46111c81404bc77a32f1d8abea6f768 (patch)
tree6f14e1eb49e1e75ad229873e3baed1f63b77e0a7 /plugins
parenta02fa40b6cc7c137089573bb67c87ca1ef7afe75 (diff)
Introduce next abstraction level of the AudioSource API
Diffstat (limited to 'plugins')
-rw-r--r--plugins/soundsourcem4a/soundsourcem4a.cpp66
-rw-r--r--plugins/soundsourcem4a/soundsourcem4a.h6
-rwxr-xr-xplugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp50
-rwxr-xr-xplugins/soundsourcemediafoundation/soundsourcemediafoundation.h6
-rw-r--r--plugins/soundsourcewv/soundsourcewv.cpp66
-rw-r--r--plugins/soundsourcewv/soundsourcewv.h6
6 files changed, 118 insertions, 82 deletions
diff --git a/plugins/soundsourcem4a/soundsourcem4a.cpp b/plugins/soundsourcem4a/soundsourcem4a.cpp
index a6b3a00308..2649ee7f07 100644
--- a/plugins/soundsourcem4a/soundsourcem4a.cpp
+++ b/plugins/soundsourcem4a/soundsourcem4a.cpp
@@ -382,32 +382,33 @@ void SoundSourceM4A::restartDecoding(MP4SampleId sampleBlockId) {
m_sampleBuffer.reset();
}
-IndexRange SoundSourceM4A::readOrSkipSampleFrames(
- IndexRange frameIndexRange,
- SampleBuffer::WritableSlice* pOutputBuffer) {
- auto readableFrames =
- adjustReadableFrameIndexRangeAndOutputBuffer(
- frameIndexRange, pOutputBuffer);
- if (readableFrames.empty()) {
- return readableFrames;
+ReadableSampleFrames SoundSourceM4A::readSampleFrames(
+ ReadMode readMode,
+ WritableSampleFrames sampleFrames) {
+ const auto writableSampleFrames =
+ clampWritableSampleFrames(readMode, sampleFrames);
+ if (writableSampleFrames.frameIndexRange().empty()) {
+ return ReadableSampleFrames(writableSampleFrames.frameIndexRange());
}
- if (m_curFrameIndex != readableFrames.start()) {
+ const SINT firstFrameIndex = writableSampleFrames.frameIndexRange().start();
+
+ if (m_curFrameIndex != firstFrameIndex) {
// NOTE(uklotzde): Resetting the decoder near to the beginning
// of the stream when seeking backwards produces invalid sample
// values! As a consequence the seeking test fails.
if ((m_curSampleBlockId != MP4_INVALID_SAMPLE_ID) &&
- (readableFrames.start() < m_curFrameIndex) &&
- (readableFrames.start() <= (frameIndexMin() + kNumberOfPrefetchFrames))) {
+ (firstFrameIndex < m_curFrameIndex) &&
+ (firstFrameIndex <= (frameIndexMin() + kNumberOfPrefetchFrames))) {
// Workaround: Reset the decoder when seeking near to the beginning
// of the stream while decoding.
reopenDecoder();
}
MP4SampleId sampleBlockId = kSampleBlockIdMin
- + (readableFrames.start() / m_framesPerSampleBlock);
+ + (firstFrameIndex / m_framesPerSampleBlock);
DEBUG_ASSERT(isValidSampleBlockId(sampleBlockId));
- if ((readableFrames.start() < m_curFrameIndex) || // seeking backwards?
+ if ((firstFrameIndex < m_curFrameIndex) || // seeking backwards?
!isValidSampleBlockId(m_curSampleBlockId) || // invalid seek position?
(sampleBlockId
> (m_curSampleBlockId + m_numberOfPrefetchSampleBlocks))) { // jumping forward?
@@ -426,20 +427,25 @@ IndexRange SoundSourceM4A::readOrSkipSampleFrames(
}
// Decoding starts before the actual target position
- DEBUG_ASSERT(m_curFrameIndex <= readableFrames.start());
+ DEBUG_ASSERT(m_curFrameIndex <= firstFrameIndex);
const auto precedingFrames =
- IndexRange::between(m_curFrameIndex, readableFrames.start());
+ IndexRange::between(m_curFrameIndex, firstFrameIndex);
if (!precedingFrames.empty()
&& (precedingFrames != skipSampleFrames(precedingFrames))) {
kLogger.warning()
<< "Failed to skip preceding frames"
<< precedingFrames;
- return IndexRange();
+ // Abort
+ return ReadableSampleFrames(
+ IndexRange::between(
+ m_curFrameIndex,
+ m_curFrameIndex));
}
}
- DEBUG_ASSERT(m_curFrameIndex == readableFrames.start());
+ DEBUG_ASSERT(m_curFrameIndex == firstFrameIndex);
+
+ const SINT numberOfSamplesTotal = frames2samples(writableSampleFrames.frameIndexRange().length());
- const SINT numberOfSamplesTotal = frames2samples(readableFrames.length());
SINT numberOfSamplesRemaining = numberOfSamplesTotal;
SINT outputSampleOffset = 0;
while (0 < numberOfSamplesRemaining) {
@@ -448,9 +454,9 @@ IndexRange SoundSourceM4A::readOrSkipSampleFrames(
// Consume previously decoded sample data
const SampleBuffer::ReadableSlice readableSlice(
m_sampleBuffer.readFromHead(numberOfSamplesRemaining));
- if (pOutputBuffer) {
+ if (readMode == ReadMode::Store) {
SampleUtil::copy(
- pOutputBuffer->data(outputSampleOffset),
+ writableSampleFrames.sampleBuffer().data(outputSampleOffset),
readableSlice.data(),
readableSlice.size());
outputSampleOffset += readableSlice.size();
@@ -499,9 +505,10 @@ IndexRange SoundSourceM4A::readOrSkipSampleFrames(
CSAMPLE* pDecodeBuffer; // in/out parameter
SINT decodeBufferCapacity;
const SINT decodeBufferCapacityMin = frames2samples(m_framesPerSampleBlock);
- if (pOutputBuffer && (decodeBufferCapacityMin <= numberOfSamplesRemaining)) {
+ if ((readMode == ReadMode::Store) &&
+ (decodeBufferCapacityMin <= numberOfSamplesRemaining)) {
// Decode samples directly into the output buffer
- pDecodeBuffer = pOutputBuffer->data(outputSampleOffset);
+ pDecodeBuffer = writableSampleFrames.sampleBuffer().data(outputSampleOffset);
decodeBufferCapacity = numberOfSamplesRemaining;
} else {
// Decode next sample block into temporary buffer
@@ -555,7 +562,8 @@ IndexRange SoundSourceM4A::readOrSkipSampleFrames(
const SINT numberOfSamplesDecoded = decFrameInfo.samples;
DEBUG_ASSERT(numberOfSamplesDecoded <= decodeBufferCapacity);
SINT numberOfSamplesRead;
- if (pOutputBuffer && (pDecodeBuffer == pOutputBuffer->data(outputSampleOffset))) {
+ if ((readMode == ReadMode::Store) &&
+ (pDecodeBuffer == writableSampleFrames.sampleBuffer().data(outputSampleOffset))) {
// Decoded in-place
DEBUG_ASSERT(numberOfSamplesDecoded <= numberOfSamplesRemaining);
numberOfSamplesRead = numberOfSamplesDecoded;
@@ -572,9 +580,9 @@ IndexRange SoundSourceM4A::readOrSkipSampleFrames(
const SampleBuffer::ReadableSlice readableSlice(
m_sampleBuffer.readFromHead(numberOfSamplesRead));
DEBUG_ASSERT(readableSlice.size() == numberOfSamplesRead);
- if (pOutputBuffer) {
+ if (readMode == ReadMode::Store) {
SampleUtil::copy(
- pOutputBuffer->data(outputSampleOffset),
+ writableSampleFrames.sampleBuffer().data(outputSampleOffset),
readableSlice.data(),
readableSlice.size());
outputSampleOffset += numberOfSamplesRead;
@@ -590,8 +598,12 @@ IndexRange SoundSourceM4A::readOrSkipSampleFrames(
DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
DEBUG_ASSERT(numberOfSamplesTotal >= numberOfSamplesRemaining);
- return readableFrames.cutFrontRange(
- samples2frames(numberOfSamplesTotal - numberOfSamplesRemaining));
+ const SINT numberOfSamples = numberOfSamplesTotal - numberOfSamplesRemaining;
+ return ReadableSampleFrames(
+ IndexRange::forward(firstFrameIndex, samples2frames(numberOfSamples)),
+ SampleBuffer::ReadableSlice(
+ writableSampleFrames.sampleBuffer().data(),
+ std::min(writableSampleFrames.sampleBuffer().size(), numberOfSamples)));
}
QString SoundSourceProviderM4A::getName() const {
diff --git a/plugins/soundsourcem4a/soundsourcem4a.h b/plugins/soundsourcem4a/soundsourcem4a.h
index e8f1950967..94088b8363 100644
--- a/plugins/soundsourcem4a/soundsourcem4a.h
+++ b/plugins/soundsourcem4a/soundsourcem4a.h
@@ -24,9 +24,9 @@ public:
void close() override;
- IndexRange readOrSkipSampleFrames(
- IndexRange frameIndexRange,
- SampleBuffer::WritableSlice* pOutputBuffer) override;
+ ReadableSampleFrames readSampleFrames(
+ ReadMode readMode,
+ WritableSampleFrames sampleFrames) override;
private:
OpenResult tryOpen(const AudioSourceConfig& audioSrcCfg) override;
diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
index d69b7d3e1a..a078b8f1dd 100755
--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
+++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp
@@ -238,26 +238,35 @@ void SoundSourceMediaFoundation::seekSampleFrame(SINT frameIndex) {
}
}
-IndexRange SoundSourceMediaFoundation::readOrSkipSampleFrames(
- IndexRange frameIndexRange,
- SampleBuffer::WritableSlice* pOutputBuffer) {
- auto readableFrames =
- adjustReadableFrameIndexRangeAndOutputBuffer(
- frameIndexRange, pOutputBuffer);
- if (readableFrames.empty()) {
- return readableFrames;
- }
-
- seekSampleFrame(readableFrames.start());
- if (m_currentFrameIndex != readableFrames.start()) {
+ReadableSampleFrames SoundSourceMediaFoundation::readSampleFrames(
+ ReadMode readMode,
+ WritableSampleFrames sampleFrames) {
+ const auto writableSampleFrames =
+ clampWritableSampleFrames(readMode, sampleFrames);
+ if (writableSampleFrames.frameIndexRange().empty()) {
+ return ReadableSampleFrames(writableSampleFrames.frameIndexRange());
+ }
+
+ const SINT firstFrameIndex = writableSampleFrames.frameIndexRange().start();
+
+ seekSampleFrame(firstFrameIndex);
+ if (m_currentFrameIndex != firstFrameIndex) {
kLogger.warning()
<< "Failed to position reader at beginning of decoding range"
- << readableFrames;
- return mixxx::IndexRange(); // abort
+ << writableSampleFrames.frameIndexRange();
+ // Abort
+ return ReadableSampleFrames(
+ mixxx::IndexRange::between(
+ m_currentFrameIndex,
+ m_currentFrameIndex));
}
+ DEBUG_ASSERT(m_curFrameIndex == firstFrameIndex);
+
+ const SINT numberOfFramesTotal = writableSampleFrames.frameIndexRange().length();
- SINT numberOfFramesRemaining = readableFrames.length();
- CSAMPLE* pSampleBuffer = pOutputBuffer ? pOutputBuffer->data() : nullptr;
+ CSAMPLE* pSampleBuffer = (readMode == ReadMode::Store) ?
+ writableSampleFrames.sampleBuffer().data() : nullptr;
+ SINT numberOfFramesRemaining = numberOfFramesTotal;
while (numberOfFramesRemaining > 0) {
SampleBuffer::ReadableSlice readableSlice(
m_sampleBuffer.readFromHead(
@@ -452,7 +461,14 @@ IndexRange SoundSourceMediaFoundation::readOrSkipSampleFrames(
}
}
- return readableFrames.cutFrontRange(readableFrames.length() - numberOfFramesRemaining);
+ DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
+ DEBUG_ASSERT(numberOfFramesTotal >= numberOfFramesRemaining);
+ const SINT numberOfFrames = numberOfFramesTotal - numberOfFramesRemaining;
+ return ReadableSampleFrames(
+ IndexRange::forward(firstFrameIndex, numberOfFrames),
+ SampleBuffer::ReadableSlice(
+ writableSampleFrames.sampleBuffer().data(),
+ std::min(writableSampleFrames.sampleBuffer().size(), frames2samples(numberOfFrames))));
}
//-------------------------------------------------------------------
diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
index 7e738a9d08..58d19934bf 100755
--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
+++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h
@@ -57,9 +57,9 @@ public:
void close() override;
- IndexRange readOrSkipSampleFrames(
- IndexRange frameIndexRange,
- SampleBuffer::WritableSlice* pOutputBuffer) override;
+ ReadableSampleFrames readSampleFrames(
+ ReadMode readMode,
+ WritableSampleFrames sampleFrames) override;
private:
OpenResult tryOpen(const mixxx::AudioSourceConfig& audioSrcCfg) override;
diff --git a/plugins/soundsourcewv/soundsourcewv.cpp b/plugins/soundsourcewv/soundsourcewv.cpp
index c5c385773d..18e0f686e5 100644
--- a/plugins/soundsourcewv/soundsourcewv.cpp
+++ b/plugins/soundsourcewv/soundsourcewv.cpp
@@ -102,26 +102,27 @@ void SoundSourceWV::close() {
}
}
-IndexRange SoundSourceWV::readOrSkipSampleFrames(
- IndexRange frameIndexRange,
- SampleBuffer::WritableSlice* pOutputBuffer) {
- auto readableFrames =
- adjustReadableFrameIndexRangeAndOutputBuffer(
- frameIndexRange, pOutputBuffer);
- if (readableFrames.empty()) {
- return readableFrames;
+ReadableSampleFrames SoundSourceWV::readSampleFrames(
+ ReadMode readMode,
+ WritableSampleFrames sampleFrames) {
+ const auto writableSampleFrames =
+ clampWritableSampleFrames(readMode, sampleFrames);
+ if (writableSampleFrames.frameIndexRange().empty()) {
+ return ReadableSampleFrames(writableSampleFrames.frameIndexRange());
}
- if (pOutputBuffer) {
- if (m_curFrameIndex != readableFrames.start()) {
- if (WavpackSeekSample(m_wpc, readableFrames.start())) {
- m_curFrameIndex = readableFrames.start();
+ const SINT firstFrameIndex = writableSampleFrames.frameIndexRange().start();
+
+ if (readMode == ReadMode::Store) {
+ if (m_curFrameIndex != firstFrameIndex) {
+ if (WavpackSeekSample(m_wpc, firstFrameIndex)) {
+ m_curFrameIndex = firstFrameIndex;
} else {
kLogger.warning()
- << "Could not seek to frame index range"
- << readableFrames;
+ << "Could not seek to first frame index"
+ << firstFrameIndex;
m_curFrameIndex = WavpackGetSampleIndex(m_wpc);
- return IndexRange();
+ return ReadableSampleFrames(IndexRange::between(m_curFrameIndex, m_curFrameIndex));
}
}
} else {
@@ -131,40 +132,47 @@ IndexRange SoundSourceWV::readOrSkipSampleFrames(
// we don't want to read samples into a temporary buffer that
// has to be allocated we are seeking to the position after
// the skipped samples.
- if (m_curFrameIndex != readableFrames.end()) {
- if (WavpackSeekSample(m_wpc, readableFrames.end())) {
- m_curFrameIndex = readableFrames.end();
- return readableFrames;
+ if (m_curFrameIndex != writableSampleFrames.frameIndexRange().end()) {
+ if (WavpackSeekSample(m_wpc, writableSampleFrames.frameIndexRange().end())) {
+ m_curFrameIndex = writableSampleFrames.frameIndexRange().end();
+ return ReadableSampleFrames(writableSampleFrames.frameIndexRange());
} else {
kLogger.warning()
<< "Could not skip frame index range"
- << readableFrames;
+ << writableSampleFrames.frameIndexRange();
m_curFrameIndex = WavpackGetSampleIndex(m_wpc);
- return IndexRange::between(m_curFrameIndex, m_curFrameIndex);
+ return ReadableSampleFrames(IndexRange::between(m_curFrameIndex, m_curFrameIndex));
}
}
}
+ DEBUG_ASSERT(m_curFrameIndex == firstFrameIndex);
+ DEBUG_ASSERT(readMode == ReadMode::Store);
+
+ const SINT numberOfFramesTotal = writableSampleFrames.frameIndexRange().length();
- DEBUG_ASSERT(m_curFrameIndex == readableFrames.start());
- DEBUG_ASSERT(pOutputBuffer);
static_assert(sizeof(CSAMPLE) == sizeof(int32_t),
"CSAMPLE and int32_t must have the same size");
+ CSAMPLE* pOutputBuffer = writableSampleFrames.sampleBuffer().data();
SINT unpackCount = WavpackUnpackSamples(m_wpc,
- reinterpret_cast<int32_t*>(pOutputBuffer->data()), readableFrames.length());
+ reinterpret_cast<int32_t*>(pOutputBuffer), numberOfFramesTotal);
DEBUG_ASSERT(unpackCount >= 0);
- DEBUG_ASSERT(unpackCount <= readableFrames.length());
+ DEBUG_ASSERT(unpackCount <= numberOfFramesTotal);
if (!(WavpackGetMode(m_wpc) & MODE_FLOAT)) {
// signed integer -> float
const SINT sampleCount = frames2samples(unpackCount);
for (SINT i = 0; i < sampleCount; ++i) {
const int32_t sampleValue =
- *reinterpret_cast<int32_t*>(pOutputBuffer->data(i));
- *pOutputBuffer->data(i) = CSAMPLE(sampleValue) * m_sampleScaleFactor;
+ *reinterpret_cast<int32_t*>(pOutputBuffer);
+ *pOutputBuffer++ = CSAMPLE(sampleValue) * m_sampleScaleFactor;
}
}
- const auto result = IndexRange::forward(m_curFrameIndex, unpackCount);
+ const auto resultRange = IndexRange::forward(m_curFrameIndex, unpackCount);
m_curFrameIndex += unpackCount;
- return result;
+ return ReadableSampleFrames(
+ resultRange,
+ SampleBuffer::ReadableSlice(
+ writableSampleFrames.sampleBuffer().data(),
+ frames2samples(unpackCount)));
}
QString SoundSourceProviderWV::getName() const {
diff --git a/plugins/soundsourcewv/soundsourcewv.h b/plugins/soundsourcewv/soundsourcewv.h
index 295a5dc9c3..5e4640a66e 100644
--- a/plugins/soundsourcewv/soundsourcewv.h
+++ b/plugins/soundsourcewv/soundsourcewv.h
@@ -16,9 +16,9 @@ class SoundSourceWV: public SoundSourcePlugin {
void close() override;
- IndexRange readOrSkipSampleFrames(
- IndexRange frameIndexRange,
- SampleBuffer::WritableSlice* pOutputBuffer) override;
+ ReadableSampleFrames readSampleFrames(
+ ReadMode readMode,
+ WritableSampleFrames sampleFrames) override;
private:
OpenResult tryOpen(const AudioSourceConfig& audioSrcCfg) override;