Made audio stream handling safe for long streams

This commit is contained in:
Daniel Wolf 2016-06-14 17:41:58 +02:00
parent d1bbe8538e
commit 522f6c2019
11 changed files with 48 additions and 48 deletions

View File

@ -9,10 +9,10 @@ public:
virtual ~AudioStream() {}
virtual std::unique_ptr<AudioStream> clone(bool reset) const = 0;
virtual int getSampleRate() const = 0;
virtual int getSampleCount() const = 0;
virtual int64_t getSampleCount() const = 0;
TimeRange getTruncatedRange() const;
virtual int getSampleIndex() const = 0;
virtual void seek(int sampleIndex) = 0;
virtual int64_t getSampleIndex() const = 0;
virtual void seek(int64_t sampleIndex) = 0;
bool endOfStream() const;
virtual float readSample() = 0;
};

View File

@ -29,15 +29,15 @@ int AudioStreamSegment::getSampleRate() const {
return audioStream->getSampleRate();
}
int AudioStreamSegment::getSampleCount() const {
int64_t AudioStreamSegment::getSampleCount() const {
return sampleCount;
}
int AudioStreamSegment::getSampleIndex() const {
int64_t AudioStreamSegment::getSampleIndex() const {
return audioStream->getSampleIndex() - sampleOffset;
}
void AudioStreamSegment::seek(int sampleIndex) {
void AudioStreamSegment::seek(int64_t sampleIndex) {
audioStream->seek(sampleIndex + sampleOffset);
}

View File

@ -8,14 +8,14 @@ public:
AudioStreamSegment(const AudioStreamSegment& rhs, bool reset);
std::unique_ptr<AudioStream> clone(bool reset) const override;
int getSampleRate() const override;
int getSampleCount() const override;
int getSampleIndex() const override;
void seek(int sampleIndex) override;
int64_t getSampleCount() const override;
int64_t getSampleIndex() const override;
void seek(int64_t sampleIndex) override;
float readSample() override;
private:
std::unique_ptr<AudioStream> audioStream;
int sampleOffset, sampleCount;
int64_t sampleOffset, sampleCount;
};
std::unique_ptr<AudioStream> createSegment(std::unique_ptr<AudioStream> audioStream, const TimeRange& range);

View File

@ -22,15 +22,15 @@ int DCOffset::getSampleRate() const {
return inputStream->getSampleRate();
}
int DCOffset::getSampleCount() const {
int64_t DCOffset::getSampleCount() const {
return inputStream->getSampleCount();
}
int DCOffset::getSampleIndex() const {
int64_t DCOffset::getSampleIndex() const {
return inputStream->getSampleIndex();
}
void DCOffset::seek(int sampleIndex) {
void DCOffset::seek(int64_t sampleIndex) {
inputStream->seek(sampleIndex);
}
@ -53,11 +53,11 @@ float getDCOffset(AudioStream& audioStream) {
fadingMeanSampleCount = 1 * sampleRate;
} else {
// Short audio file. Average over the entire length.
flatMeanSampleCount = audioStream.getSampleCount();
flatMeanSampleCount = static_cast<int>(audioStream.getSampleCount());
fadingMeanSampleCount = 0;
}
int originalSampleIndex = audioStream.getSampleIndex();
int64_t originalSampleIndex = audioStream.getSampleIndex();
audioStream.seek(0);
auto restorePosition = gsl::finally([&]() { audioStream.seek(originalSampleIndex); });

View File

@ -10,9 +10,9 @@ public:
DCOffset(const DCOffset& rhs, bool reset);
std::unique_ptr<AudioStream> clone(bool reset) const override;
int getSampleRate() const override;
int getSampleCount() const override;
int getSampleIndex() const override;
void seek(int sampleIndex) override;
int64_t getSampleCount() const override;
int64_t getSampleIndex() const override;
void seek(int64_t sampleIndex) override;
float readSample() override;
private:

View File

@ -37,15 +37,15 @@ int SampleRateConverter::getSampleRate() const {
return outputSampleRate;
}
int SampleRateConverter::getSampleCount() const {
int64_t SampleRateConverter::getSampleCount() const {
return outputSampleCount;
}
int SampleRateConverter::getSampleIndex() const {
int64_t SampleRateConverter::getSampleIndex() const {
return nextOutputSampleIndex;
}
void SampleRateConverter::seek(int sampleIndex) {
void SampleRateConverter::seek(int64_t sampleIndex) {
if (sampleIndex < 0 || sampleIndex >= outputSampleCount) throw std::invalid_argument("sampleIndex out of range.");
nextOutputSampleIndex = sampleIndex;
@ -66,12 +66,12 @@ float SampleRateConverter::mean(double inputStart, double inputEnd) {
double sum = 0;
// ... first sample (weight <= 1)
int startIndex = static_cast<int>(inputStart);
int64_t startIndex = static_cast<int64_t>(inputStart);
sum += getInputSample(startIndex) * ((startIndex + 1) - inputStart);
// ... middle samples (weight 1 each)
int endIndex = static_cast<int>(inputEnd);
for (int index = startIndex + 1; index < endIndex; index++) {
int64_t endIndex = static_cast<int64_t>(inputEnd);
for (int64_t index = startIndex + 1; index < endIndex; ++index) {
sum += getInputSample(index);
}
@ -81,7 +81,7 @@ float SampleRateConverter::mean(double inputStart, double inputEnd) {
return static_cast<float>(sum / (inputEnd - inputStart));
}
float SampleRateConverter::getInputSample(int sampleIndex) {
float SampleRateConverter::getInputSample(int64_t sampleIndex) {
sampleIndex = std::min(sampleIndex, inputStream->getSampleCount() - 1);
if (sampleIndex < 0) return 0.0f;

View File

@ -9,24 +9,24 @@ public:
SampleRateConverter(const SampleRateConverter& rhs, bool reset);
std::unique_ptr<AudioStream> clone(bool reset) const override;
int getSampleRate() const override;
int getSampleCount() const override;
int getSampleIndex() const override;
void seek(int sampleIndex) override;
int64_t getSampleCount() const override;
int64_t getSampleIndex() const override;
void seek(int64_t sampleIndex) override;
float readSample() override;
private:
std::unique_ptr<AudioStream> inputStream;
double downscalingFactor; // input sample rate / output sample rate
int outputSampleRate;
int outputSampleCount;
int64_t outputSampleCount;
float lastInputSample;
int lastInputSampleIndex;
int64_t lastInputSampleIndex;
int nextOutputSampleIndex;
int64_t nextOutputSampleIndex;
float mean(double start, double end);
float getInputSample(int sampleIndex);
float getInputSample(int64_t sampleIndex);
};
std::unique_ptr<AudioStream> convertSampleRate(std::unique_ptr<AudioStream> audioStream, int sampleRate);

View File

@ -24,15 +24,15 @@ int UnboundedStream::getSampleRate() const {
return innerStream->getSampleRate();
}
int UnboundedStream::getSampleCount() const {
int64_t UnboundedStream::getSampleCount() const {
return innerStream->getSampleCount();
}
int UnboundedStream::getSampleIndex() const {
int64_t UnboundedStream::getSampleIndex() const {
return sampleIndex;
}
void UnboundedStream::seek(int sampleIndex) {
void UnboundedStream::seek(int64_t sampleIndex) {
this->sampleIndex = sampleIndex;
}

View File

@ -10,13 +10,13 @@ public:
UnboundedStream(const UnboundedStream& rhs, bool reset);
std::unique_ptr<AudioStream> clone(bool reset) const override;
int getSampleRate() const override;
int getSampleCount() const override;
int getSampleIndex() const override;
void seek(int sampleIndex) override;
int64_t getSampleCount() const override;
int64_t getSampleIndex() const override;
void seek(int64_t sampleIndex) override;
float readSample() override;
private:
std::unique_ptr<AudioStream> innerStream;
int sampleIndex;
int64_t sampleIndex;
boost::optional<float> firstSample, lastSample;
};

View File

@ -173,15 +173,15 @@ int WaveFileReader::getSampleRate() const {
return frameRate;
}
int WaveFileReader::getSampleCount() const {
int64_t WaveFileReader::getSampleCount() const {
return frameCount;
}
int WaveFileReader::getSampleIndex() const {
int64_t WaveFileReader::getSampleIndex() const {
return sampleIndex;
}
void WaveFileReader::seek(int sampleIndex) {
void WaveFileReader::seek(int64_t sampleIndex) {
if (sampleIndex < 0 || sampleIndex > sampleCount) throw std::invalid_argument("sampleIndex out of range.");
file.seekg(dataOffset + static_cast<std::streamoff>(sampleIndex * channelCount * bytesPerSample));

View File

@ -17,9 +17,9 @@ public:
WaveFileReader(const WaveFileReader& rhs, bool reset);
std::unique_ptr<AudioStream> clone(bool reset) const override;
int getSampleRate() const override ;
int getSampleCount() const override;
int getSampleIndex() const override;
void seek(int sampleIndex) override;
int64_t getSampleCount() const override;
int64_t getSampleIndex() const override;
void seek(int64_t sampleIndex) override;
float readSample() override;
private:
@ -31,9 +31,9 @@ private:
int bytesPerSample;
SampleFormat sampleFormat;
int frameRate;
int frameCount;
int64_t frameCount;
int channelCount;
int sampleCount;
int64_t sampleCount;
std::streampos dataOffset;
int sampleIndex;
int64_t sampleIndex;
};