diff --git a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp index 9839b831b8..34bbc494ef 100644 --- a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp @@ -166,11 +166,11 @@ namespace WavFileHelpers struct BWAVChunk { - char description [256]; - char originator [32]; - char originatorRef [32]; - char originationDate [10]; - char originationTime [8]; + char description[256]; + char originator[32]; + char originatorRef[32]; + char originationDate[10]; + char originationTime[8]; uint32 timeRefLow; uint32 timeRefHigh; uint16 version; @@ -186,9 +186,9 @@ namespace WavFileHelpers values.set (WavAudioFormat::bwavOriginationDate, String::fromUTF8 (originationDate, sizeof (originationDate))); values.set (WavAudioFormat::bwavOriginationTime, String::fromUTF8 (originationTime, sizeof (originationTime))); - const uint32 timeLow = ByteOrder::swapIfBigEndian (timeRefLow); - const uint32 timeHigh = ByteOrder::swapIfBigEndian (timeRefHigh); - const int64 time = (((int64) timeHigh) << 32) + timeLow; + auto timeLow = ByteOrder::swapIfBigEndian (timeRefLow); + auto timeHigh = ByteOrder::swapIfBigEndian (timeRefHigh); + auto time = (((int64) timeHigh) << 32) + timeLow; values.set (WavAudioFormat::bwavTimeReference, String (time)); values.set (WavAudioFormat::bwavCodingHistory, @@ -197,24 +197,24 @@ namespace WavFileHelpers static MemoryBlock createFrom (const StringPairArray& values) { - MemoryBlock data (roundUpSize (sizeof (BWAVChunk) + values [WavAudioFormat::bwavCodingHistory].getNumBytesAsUTF8())); + MemoryBlock data (roundUpSize (sizeof (BWAVChunk) + values[WavAudioFormat::bwavCodingHistory].getNumBytesAsUTF8())); data.fillWith (0); BWAVChunk* b = (BWAVChunk*) data.getData(); // Allow these calls to overwrite an extra byte at the end, which is fine as long // as they get called in the right order.. - values [WavAudioFormat::bwavDescription] .copyToUTF8 (b->description, 257); - values [WavAudioFormat::bwavOriginator] .copyToUTF8 (b->originator, 33); - values [WavAudioFormat::bwavOriginatorRef] .copyToUTF8 (b->originatorRef, 33); - values [WavAudioFormat::bwavOriginationDate].copyToUTF8 (b->originationDate, 11); - values [WavAudioFormat::bwavOriginationTime].copyToUTF8 (b->originationTime, 9); + values[WavAudioFormat::bwavDescription] .copyToUTF8 (b->description, 257); + values[WavAudioFormat::bwavOriginator] .copyToUTF8 (b->originator, 33); + values[WavAudioFormat::bwavOriginatorRef] .copyToUTF8 (b->originatorRef, 33); + values[WavAudioFormat::bwavOriginationDate].copyToUTF8 (b->originationDate, 11); + values[WavAudioFormat::bwavOriginationTime].copyToUTF8 (b->originationTime, 9); - const int64 time = values [WavAudioFormat::bwavTimeReference].getLargeIntValue(); + auto time = values[WavAudioFormat::bwavTimeReference].getLargeIntValue(); b->timeRefLow = ByteOrder::swapIfBigEndian ((uint32) (time & 0xffffffff)); b->timeRefHigh = ByteOrder::swapIfBigEndian ((uint32) (time >> 32)); - values [WavAudioFormat::bwavCodingHistory].copyToUTF8 (b->codingHistory, 0x7fffffff); + values[WavAudioFormat::bwavCodingHistory].copyToUTF8 (b->codingHistory, 0x7fffffff); if (b->description[0] != 0 || b->originator[0] != 0 @@ -321,7 +321,7 @@ namespace WavFileHelpers static MemoryBlock createFrom (const StringPairArray& values) { MemoryBlock data; - const int numLoops = jmin (64, values.getValue ("NumSampleLoops", "0").getIntValue()); + auto numLoops = jmin (64, values.getValue ("NumSampleLoops", "0").getIntValue()); data.setSize (roundUpSize (sizeof (SMPLChunk) + (size_t) (jmax (0, numLoops - 1)) * sizeof (SampleLoop)), true); @@ -528,7 +528,7 @@ namespace WavFileHelpers auto text = values.getValue (prefix + "Text", prefix); auto textLength = (int) text.getNumBytesAsUTF8() + 1; // include null terminator - int chunkLength = textLength + 20 + (textLength & 1); + auto chunkLength = textLength + 20 + (textLength & 1); out.writeInt (chunkName ("ltxt")); out.writeInt (chunkLength); @@ -673,9 +673,8 @@ namespace WavFileHelpers { while (input.getPosition() < chunkEnd) { - const int infoType = input.readInt(); - - int64 infoLength = chunkEnd - input.getPosition(); + auto infoType = input.readInt(); + auto infoLength = chunkEnd - input.getPosition(); if (infoLength > 0) { @@ -706,8 +705,8 @@ namespace WavFileHelpers if (value.isEmpty()) return false; - const int valueLength = (int) value.getNumBytesAsUTF8() + 1; - const int chunkLength = valueLength + (valueLength & 1); + auto valueLength = (int) value.getNumBytesAsUTF8() + 1; + auto chunkLength = valueLength + (valueLength & 1); out.writeInt (chunkName (paramName)); out.writeInt (chunkLength); @@ -831,7 +830,7 @@ namespace WavFileHelpers static MemoryBlock createFrom (const StringPairArray& values) { MemoryOutputStream out; - const String s (values[WavAudioFormat::tracktionLoopInfo]); + auto s = values[WavAudioFormat::tracktionLoopInfo]; if (s.isNotEmpty()) { @@ -934,17 +933,16 @@ namespace WavFileHelpers class WavAudioFormatReader : public AudioFormatReader { public: - WavAudioFormatReader (InputStream* const in) - : AudioFormatReader (in, wavFormatName) + WavAudioFormatReader (InputStream* in) : AudioFormatReader (in, wavFormatName) { using namespace WavFileHelpers; - uint64 len = 0; - uint64 end = 0; + uint64 len = 0, end = 0; int cueNoteIndex = 0; int cueLabelIndex = 0; int cueRegionIndex = 0; - const int firstChunkType = input->readInt(); + auto streamStartPos = input->getPosition(); + auto firstChunkType = input->readInt(); if (firstChunkType == chunkName ("RF64")) { @@ -967,12 +965,12 @@ public: { if (isRF64 && input->readInt() == chunkName ("ds64")) { - const uint32 length = (uint32) input->readInt(); + auto length = (uint32) input->readInt(); if (length < 28) return; - const int64 chunkEnd = input->getPosition() + length + (length & 1); + auto chunkEnd = input->getPosition() + length + (length & 1); len = (uint64) input->readInt64(); end = len + (uint64) startOfRIFFChunk; dataLength = input->readInt64(); @@ -981,9 +979,9 @@ public: while ((uint64) input->getPosition() < end && ! input->isExhausted()) { - const int chunkType = input->readInt(); - uint32 length = (uint32) input->readInt(); - const int64 chunkEnd = input->getPosition() + length + (length & 1); + auto chunkType = input->readInt(); + auto length = (uint32) input->readInt(); + auto chunkEnd = input->getPosition() + length + (length & 1); if (chunkType == chunkName ("fmt ")) { @@ -1009,7 +1007,7 @@ public: { usesFloatingPointData = true; } - else if (format == 0xfffe /*WAVE_FORMAT_EXTENSIBLE*/) + else if (format == 0xfffe) // WAVE_FORMAT_EXTENSIBLE { if (length < 40) // too short { @@ -1034,6 +1032,18 @@ public: bytesPerFrame = 0; } } + else if (format == 0x674f // WAVE_FORMAT_OGG_VORBIS_MODE_1 + || format == 0x6750 // WAVE_FORMAT_OGG_VORBIS_MODE_2 + || format == 0x6751 // WAVE_FORMAT_OGG_VORBIS_MODE_3 + || format == 0x676f // WAVE_FORMAT_OGG_VORBIS_MODE_1_PLUS + || format == 0x6770 // WAVE_FORMAT_OGG_VORBIS_MODE_2_PLUS + || format == 0x6771) // WAVE_FORMAT_OGG_VORBIS_MODE_3_PLUS + { + isSubformatOggVorbis = true; + sampleRate = 0; // to mark the wav reader as failed + input->setPosition (streamStartPos); + return; + } else if (format != 1) { bytesPerFrame = 0; @@ -1187,7 +1197,7 @@ public: while (numSamples > 0) { const int tempBufSize = 480 * 3 * 4; // (keep this a multiple of 3) - char tempBuffer [tempBufSize]; + char tempBuffer[tempBufSize]; const int numThisTime = jmin (tempBufSize / bytesPerFrame, numSamples); const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); @@ -1267,6 +1277,8 @@ public: int64 dataChunkStart = 0, dataLength = 0; int bytesPerFrame = 0; bool isRF64 = false; + bool isSubformatOggVorbis = false; + AudioChannelSet channelLayout; private: @@ -1596,7 +1608,7 @@ public: jassert (numSamples <= 0); // you must make sure that the window contains all the samples you're going to attempt to read. for (int i = 0; i < numChannelsToRead; ++i) - results[i] = Range(); + results[i] = {}; return; } @@ -1630,17 +1642,13 @@ WavAudioFormat::~WavAudioFormat() {} Array WavAudioFormat::getPossibleSampleRates() { - const int rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, 44100, - 48000, 88200, 96000, 176400, 192000, 352800, 384000 }; - - return Array (rates, numElementsInArray (rates)); + return { 8000, 11025, 12000, 16000, 22050, 32000, 44100, + 48000, 88200, 96000, 176400, 192000, 352800, 384000 }; } Array WavAudioFormat::getPossibleBitDepths() { - const int depths[] = { 8, 16, 24, 32 }; - - return Array (depths, numElementsInArray (depths)); + return { 8, 16, 24, 32 }; } bool WavAudioFormat::canDoStereo() { return true; } @@ -1662,11 +1670,18 @@ bool WavAudioFormat::isChannelLayoutSupported (const AudioChannelSet& channelSet return true; } -AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails) +AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream, bool deleteStreamIfOpeningFails) { ScopedPointer r (new WavAudioFormatReader (sourceStream)); + #if JUCE_USE_OGGVORBIS + if (r->isSubformatOggVorbis) + { + r->input = nullptr; + return OggVorbisAudioFormat().createReaderFor (sourceStream, deleteStreamIfOpeningFails); + } + #endif + if (r->sampleRate > 0 && r->numChannels > 0 && r->bytesPerFrame > 0) return r.release(); @@ -1758,7 +1773,7 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai if (bwavSize > 0) { - MemoryBlock chunk (BWAVChunk::createFrom (newMetadata)); + auto chunk = BWAVChunk::createFrom (newMetadata); if (chunk.getSize() <= (size_t) bwavSize) { @@ -1768,7 +1783,7 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai { FileOutputStream out (wavFile); - if (! out.failedToOpen()) + if (out.openedOk()) { out.setPosition (bwavPos); out << chunk; @@ -1777,7 +1792,6 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai } jassert (wavFile.getSize() == oldSize); - return true; } }