wav streaming fix

This commit is contained in:
MihailRis
2024-03-01 19:03:27 +03:00
parent 603546f642
commit 011bdd8397
2 changed files with 38 additions and 8 deletions
+3
View File
@@ -27,6 +27,9 @@ size_t PCMStream::readFully(char* buffer, size_t bufferSize, bool loop) {
do { do {
do { do {
bytes = read(buffer, bufferSize); bytes = read(buffer, bufferSize);
if (bytes < 0) {
return size;
}
size += bytes; size += bytes;
bufferSize -= bytes; bufferSize -= bytes;
buffer += bytes; buffer += bytes;
+35 -8
View File
@@ -43,15 +43,16 @@ public:
uint channels, uint channels,
uint bitsPerSample, uint bitsPerSample,
uint sampleRate, uint sampleRate,
size_t size size_t size,
) : in(std::move(in)), size_t initialPosition
) : in(std::move(in)),
channels(channels), channels(channels),
bytesPerSample(bitsPerSample/8), bytesPerSample(bitsPerSample/8),
sampleRate(sampleRate), sampleRate(sampleRate),
totalSize(size) totalSize(size)
{ {
totalSamples = totalSize / channels / bytesPerSample; totalSamples = totalSize / channels / bytesPerSample;
initialPosition = in.tellg(); this->initialPosition = initialPosition;
} }
size_t read(char* buffer, size_t bufferSize) override { size_t read(char* buffer, size_t bufferSize) override {
@@ -59,10 +60,13 @@ public:
return 0; return 0;
} }
in.read(buffer, bufferSize); in.read(buffer, bufferSize);
if (in.failbit) { if (in.eof()) {
std::cerr << "Wav::load_pcm: I/O error ocurred" << std::endl;
return 0; return 0;
} }
if (in.fail()) {
std::cerr << "Wav::load_pcm: I/O error ocurred" << std::endl;
return -1;
}
return in.gcount(); return in.gcount();
} }
@@ -104,7 +108,8 @@ public:
if (!isOpen()) if (!isOpen())
return; return;
position %= totalSamples; position %= totalSamples;
in.seekg(initialPosition + position * channels * bytesPerSample); in.clear();
in.seekg(initialPosition + position * channels * bytesPerSample, std::ios_base::beg);
} }
}; };
@@ -114,7 +119,7 @@ audio::PCMStream* wav::create_stream(const std::filesystem::path& file) {
throw std::runtime_error("could not to open file '"+file.u8string()+"'"); throw std::runtime_error("could not to open file '"+file.u8string()+"'");
} }
char buffer[4]; char buffer[6];
// the RIFF // the RIFF
if(!in.read(buffer, 4)){ if(!in.read(buffer, 4)){
throw std::runtime_error("could not to read RIFF"); throw std::runtime_error("could not to read RIFF");
@@ -164,12 +169,34 @@ audio::PCMStream* wav::create_stream(const std::filesystem::path& file) {
throw std::runtime_error("could not read bits per sample"); throw std::runtime_error("could not read bits per sample");
} }
int bitsPerSample = convert_to_int(buffer, 2); int bitsPerSample = convert_to_int(buffer, 2);
if (bitsPerSample >= 24) {
throw std::runtime_error(std::to_string(bitsPerSample)+" bit depth is not supported by OpenAL");
}
// data chunk header "data" // data chunk header "data"
if(!in.read(buffer, 4)){ if(!in.read(buffer, 4)){
throw std::runtime_error("could not read data chunk header"); throw std::runtime_error("could not read data chunk header");
} }
size_t initialOffset = 44;
// skip garbage in WAV
if (std::strncmp(buffer, "LIST", 4) == 0) {
// chunk size
if(!in.read(buffer, 4)){
throw std::runtime_error("could not read comment chunk size");
}
int chunkSize = convert_to_int(buffer, 4);
in.seekg(chunkSize, std::ios_base::cur);
initialOffset += chunkSize + 4;
if(!in.read(buffer, 4)){
throw std::runtime_error("could not read data chunk header");
}
}
if(std::strncmp(buffer, "data", 4) != 0){ if(std::strncmp(buffer, "data", 4) != 0){
std::cerr << buffer << std::endl;
throw std::runtime_error("file is not a valid WAVE file (doesn't have 'data' tag)"); throw std::runtime_error("file is not a valid WAVE file (doesn't have 'data' tag)");
} }
@@ -186,7 +213,7 @@ audio::PCMStream* wav::create_stream(const std::filesystem::path& file) {
if(in.fail()){ if(in.fail()){
throw std::runtime_error("fail state set on the file"); throw std::runtime_error("fail state set on the file");
} }
return new WavStream(std::move(in), channels, bitsPerSample, sampleRate, size); return new WavStream(std::move(in), channels, bitsPerSample, sampleRate, size, initialOffset);
} }
audio::PCM* wav::load_pcm(const std::filesystem::path& file, bool headerOnly) { audio::PCM* wav::load_pcm(const std::filesystem::path& file, bool headerOnly) {