29using StringMap = std::unordered_map<String, String>;
35 for (
auto i = 0;
i < array.
size(); ++
i)
43 const auto iter =
m.find (
key);
44 return iter !=
m.cend() ? iter->second : fallback;
60 const String& originatorRef,
62 int64 timeReferenceSamples,
63 const String& codingHistory)
264 constexpr inline size_t roundUpSize (
size_t sz)
noexcept {
return (sz + 3) & ~3u; }
267 #pragma pack (push, 1)
294 auto time = (((
int64) timeHigh) << 32) + timeLow;
321 if (
b->description[0] != 0
322 ||
b->originator[0] != 0
323 ||
b->originationDate[0] != 0
324 ||
b->originationTime[0] != 0
325 ||
b->codingHistory[0] != 0
375 template <
typename NameType>
412 template <
typename NameType>
432 s->manufacturer =
getValue (values,
"Manufacturer",
"0");
433 s->product =
getValue (values,
"Product",
"0");
434 s->samplePeriod =
getValue (values,
"SamplePeriod",
"0");
435 s->midiUnityNote =
getValue (values,
"MidiUnityNote",
"60");
436 s->midiPitchFraction =
getValue (values,
"MidiPitchFraction",
"0");
437 s->smpteFormat =
getValue (values,
"SmpteFormat",
"0");
438 s->smpteOffset =
getValue (values,
"SmpteOffset",
"0");
440 s->samplerData =
getValue (values,
"SamplerData",
"0");
442 for (
int i = 0;
i < numLoops; ++
i)
493 if ( values.find (
"LowNote") != values.cend()
494 && values.find (
"HighNote") != values.cend())
496 data.setSize (8,
true);
500 inst->detune =
getValue (values,
"Detune",
"0");
501 inst->gain =
getValue (values,
"Gain",
"0");
502 inst->lowNote =
getValue (values,
"LowNote",
"0");
503 inst->highNote =
getValue (values,
"HighNote",
"127");
504 inst->lowVelocity =
getValue (values,
"LowVelocity",
"1");
505 inst->highVelocity =
getValue (values,
"HighVelocity",
"127");
573 auto prefix =
"Cue" +
String (
i);
578 identifiers.
add (identifier);
582 nextOrder =
jmax (nextOrder, order) + 1;
584 auto& cue =
c->cues[
i];
616 auto labelLength = (
int)
label.getNumBytesAsUTF8() + 1;
617 auto chunkLength = 4 + labelLength + (labelLength & 1);
619 out.writeInt (chunkType);
620 out.writeInt (chunkLength);
621 out.writeInt (
getValue (values, prefix,
"Identifier"));
622 out.write (
label.toUTF8(), (
size_t) labelLength);
624 if ((
out.getDataSize() & 1) != 0)
632 auto textLength = (
int)
text.getNumBytesAsUTF8() + 1;
633 auto chunkLength = textLength + 20 + (textLength & 1);
636 out.writeInt (chunkLength);
637 out.writeInt (
getValue (values, prefix,
"Identifier"));
638 out.writeInt (
getValue (values, prefix,
"SampleLength"));
639 out.writeInt (
getValue (values, prefix,
"Purpose"));
640 out.writeShort ((
short)
getValue (values, prefix,
"Country"));
641 out.writeShort ((
short)
getValue (values, prefix,
"Language"));
642 out.writeShort ((
short)
getValue (values, prefix,
"Dialect"));
643 out.writeShort ((
short)
getValue (values, prefix,
"CodePage"));
644 out.write (
text.toUTF8(), (
size_t) textLength);
646 if ((
out.getDataSize() & 1) != 0)
652 auto numCueLabels =
getValue (values,
"NumCueLabels");
653 auto numCueNotes =
getValue (values,
"NumCueNotes");
654 auto numCueRegions =
getValue (values,
"NumCueRegions");
658 if (numCueLabels + numCueNotes + numCueRegions > 0)
662 for (
int i = 0;
i < numCueLabels; ++
i)
665 for (
int i = 0;
i < numCueNotes; ++
i)
668 for (
int i = 0;
i < numCueRegions; ++
i)
672 return out.getMemoryBlock();
767 for (
int i = 0;
i < 4; ++
i)
778 auto infoType = input.
readInt();
810 auto valueLength = (
int)
value.getNumBytesAsUTF8() + 1;
811 auto chunkLength = valueLength + (valueLength & 1);
814 out.writeInt (chunkLength);
815 out.write (
value.toUTF8(), (
size_t) valueLength);
817 if ((
out.getDataSize() & 1) != 0)
827 bool anyParamsDefined =
false;
831 anyParamsDefined =
true;
866 if (iter != values.cend())
872 return AcidChunk (values).toMemoryBlock();
910 #ifdef JUCE_BIG_ENDIAN
911 union {
uint32 asInt;
float asFloat; }
n;
943 if ((
out.getDataSize() & 1) != 0)
947 return out.getMemoryBlock();
1045 if (xml->hasTagName (
"BWFXML"))
1050 if (
const auto* aswgElement = xml->getChildByName (
"ASWG"))
1052 for (
const auto* entry : aswgElement->getChildIterator())
1054 const auto& tag = entry->getTagName();
1057 destValues[tag] = entry->getAllSubText();
1069 elem->addTextElement (
value);
1073 std::unique_ptr<XmlElement> aswgElement;
1075 for (
const auto& pair : values)
1079 if (aswgElement ==
nullptr)
1080 aswgElement = std::make_unique<XmlElement> (
"ASWG");
1082 aswgElement->addChildElement (createTextElement (pair.first, pair.second));
1088 if (aswgElement !=
nullptr)
1109 if (xml->hasTagName (
"ebucore:ebuCoreMain"))
1111 if (
auto xml2 = xml->getChildByName (
"ebucore:coreMetadata"))
1113 if (
auto xml3 = xml2->getChildByName (
"ebucore:identifier"))
1115 if (
auto xml4 = xml3->getChildByName (
"dc:identifier"))
1117 auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf (
"ISRC:",
false,
true);
1119 if (ISRCCode.isNotEmpty())
1143 if (ISRC.isNotEmpty())
1151 jassert (ISRC.length() == 12);
1153 xml <<
"<ebucore:ebuCoreMain xmlns:dc=\" http://purl.org/dc/elements/1.1/\" "
1154 "xmlns:ebucore=\"urn:ebu:metadata-schema:ebuCore_2012\">"
1155 "<ebucore:coreMetadata>"
1156 "<ebucore:identifier typeLabel=\"GUID\" "
1157 "typeDefinition=\"Globally Unique Identifier\" "
1158 "formatLabel=\"ISRC\" "
1159 "formatDefinition=\"International Standard Recording Code\" "
1160 "formatLink=\"http://www.ebu.ch/metadata/cs/ebu_IdentifierTypeCodeCS.xml#3.7\">"
1161 "<dc:identifier>ISRC:" << ISRC <<
"</dc:identifier>"
1162 "</ebucore:identifier>"
1163 "</ebucore:coreMetadata>"
1164 "</ebucore:ebuCoreMain>";
1186 static const ExtensibleWavSubFormat pcmFormat = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
1187 static const ExtensibleWavSubFormat IEEEFloatFormat = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
1188 static const ExtensibleWavSubFormat ambisonicFormat = { 0x00000001, 0x0721, 0x11d3, { 0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 } };
1214 int cueNoteIndex = 0;
1215 int cueLabelIndex = 0;
1216 int cueRegionIndex = 0;
1220 auto streamStartPos =
input->getPosition();
1221 auto firstChunkType =
input->readInt();
1223 if (firstChunkType == chunkName (
"RF64"))
1225 input->skipNextBytes (4);
1228 else if (firstChunkType == chunkName (
"RIFF"))
1238 auto startOfRIFFChunk =
input->getPosition();
1240 if (
input->readInt() == chunkName (
"WAVE"))
1242 if (
isRF64 &&
input->readInt() == chunkName (
"ds64"))
1253 input->setPosition (chunkEnd);
1258 auto chunkType =
input->readInt();
1262 if (chunkType == chunkName (
"fmt "))
1265 auto format = (
unsigned short)
input->readShort();
1268 auto bytesPerSec =
input->readInt();
1269 input->skipNextBytes (2);
1288 else if (
format == 0xfffe)
1296 input->skipNextBytes (4);
1297 auto channelMask =
input->readInt();
1298 dict[
"ChannelMask"] =
String (channelMask);
1301 ExtensibleWavSubFormat subFormat;
1305 input->read (subFormat.data4, sizeof (subFormat.data4));
1307 if (subFormat == IEEEFloatFormat)
1309 else if (subFormat != pcmFormat && subFormat != ambisonicFormat)
1313 else if (
format == 0x674f
1322 input->setPosition (streamStartPos);
1330 else if (chunkType == chunkName (
"data"))
1345 else if (chunkType == chunkName (
"bext"))
1353 bwav->copyTo (dict, (
int)
length);
1355 else if (chunkType == chunkName (
"smpl"))
1360 smpl->copyTo (dict, (
int)
length);
1362 else if (chunkType == chunkName (
"inst") || chunkType == chunkName (
"INST"))
1367 inst->copyTo (dict);
1369 else if (chunkType == chunkName (
"cue "))
1374 cue->copyTo (dict, (
int)
length);
1376 else if (chunkType == chunkName (
"axml"))
1379 input->readIntoMemoryBlock (axml, (ssize_t)
length);
1380 AXMLChunk::addToMetadata (dict, axml.
toString());
1382 else if (chunkType == chunkName (
"iXML"))
1385 input->readIntoMemoryBlock (ixml, (ssize_t)
length);
1386 IXMLChunk::addToMetadata (dict, ixml.
toString());
1388 else if (chunkType == chunkName (
"LIST"))
1390 auto subChunkType =
input->readInt();
1392 if (subChunkType == chunkName (
"info") || subChunkType == chunkName (
"INFO"))
1394 ListInfoChunk::addToMetadata (dict, *
input, chunkEnd);
1396 else if (subChunkType == chunkName (
"adtl"))
1398 while (
input->getPosition() < chunkEnd)
1400 auto adtlChunkType =
input->readInt();
1402 auto adtlChunkEnd =
input->getPosition() + (adtlLength + (adtlLength & 1));
1404 if (adtlChunkType == chunkName (
"labl") || adtlChunkType == chunkName (
"note"))
1408 if (adtlChunkType == chunkName (
"labl"))
1409 prefix <<
"CueLabel" << cueLabelIndex++;
1410 else if (adtlChunkType == chunkName (
"note"))
1411 prefix <<
"CueNote" << cueNoteIndex++;
1414 auto stringLength = (
int) adtlLength - 4;
1417 input->readIntoMemoryBlock (textBlock, stringLength);
1419 dict[prefix +
"Identifier"] =
String (identifier);
1420 dict[prefix +
"Text"] = textBlock.
toString();
1422 else if (adtlChunkType == chunkName (
"ltxt"))
1424 auto prefix =
"CueRegion" +
String (cueRegionIndex++);
1432 auto stringLength = adtlLength - 20;
1435 input->readIntoMemoryBlock (textBlock, (
int) stringLength);
1437 dict[prefix +
"Identifier"] =
String (identifier);
1438 dict[prefix +
"SampleLength"] =
String (sampleLength);
1439 dict[prefix +
"Purpose"] =
String (purpose);
1440 dict[prefix +
"Country"] =
String (country);
1441 dict[prefix +
"Language"] =
String (language);
1442 dict[prefix +
"Dialect"] =
String (dialect);
1443 dict[prefix +
"CodePage"] =
String (codePage);
1444 dict[prefix +
"Text"] = textBlock.
toString();
1447 input->setPosition (adtlChunkEnd);
1451 else if (chunkType == chunkName (
"acid"))
1455 else if (chunkType == chunkName (
"Trkn"))
1458 input->readIntoMemoryBlock (tracktion, (ssize_t)
length);
1461 else if (chunkEnd <= input->getPosition())
1466 input->setPosition (chunkEnd);
1470 if (cueLabelIndex > 0) dict[
"NumCueLabels"] =
String (cueLabelIndex);
1471 if (cueNoteIndex > 0) dict[
"NumCueNotes"] =
String (cueNoteIndex);
1472 if (cueRegionIndex > 0) dict[
"NumCueRegions"] =
String (cueRegionIndex);
1473 if (dict.size() > 0) dict[
"MetaDataSource"] =
"WAV";
1479 bool readSamples (
int** destSamples,
int numDestChannels,
int startOffsetInDestBuffer,
1480 int64 startSampleInFile,
int numSamples)
override
1485 if (numSamples <= 0)
1490 while (numSamples > 0)
1492 const int tempBufSize = 480 * 3 * 4;
1493 char tempBuffer[tempBufSize];
1505 destSamples, startOffsetInDestBuffer, numDestChannels,
1508 startOffsetInDestBuffer += numThisTime;
1509 numSamples -= numThisTime;
1515 static void copySampleData (
unsigned int numBitsPerSample,
const bool floatingPointData,
1516 int*
const* destSamples,
int startOffsetInDestBuffer,
int numDestChannels,
1517 const void* sourceData,
int numberOfChannels,
int numSamples)
noexcept
1519 switch (numBitsPerSample)
1551 if (wavFileChannelLayout.
size() !=
static_cast<int> (totalNumChannels))
1555 if (totalNumChannels <= 2 && dwChannelMask == 0)
1561 while (wavFileChannelLayout.
size() <
static_cast<int> (totalNumChannels))
1566 return wavFileChannelLayout;
1592 if (metadataValues.
size() > 0)
1597 jassert (metadataValues.getValue (
"MetaDataSource",
"None") !=
"AIFF");
1599 const auto map = toMap (metadataValues);
1601 bwavChunk = BWAVChunk::createFrom (map);
1602 ixmlChunk = IXMLChunk::createFrom (map);
1603 axmlChunk = AXMLChunk::createFrom (map);
1604 smplChunk = SMPLChunk::createFrom (map);
1605 instChunk = InstChunk::createFrom (map);
1606 cueChunk = CueChunk ::createFrom (map);
1607 listChunk = ListChunk::createFrom (map);
1608 listInfoChunk = ListInfoChunk::createFrom (map);
1609 acidChunk = AcidChunk::createFrom (map);
1610 trckChunk = TracktionChunk::createFrom (map);
1660 auto lastWritePos =
output->getPosition();
1663 if (
output->setPosition (lastWritePos))
1673 MemoryBlock tempBlock,
bwavChunk,
ixmlChunk,
axmlChunk,
smplChunk,
instChunk,
cueChunk,
listChunk,
listInfoChunk,
acidChunk,
trckChunk;
1698 const bool isWaveFmtEx = isRF64 || (channelMask != 0);
1701 + 8 + audioDataSize + (audioDataSize & 1)
1714 riffChunkSize += (riffChunkSize & 1);
1721 output->writeInt (chunkName (
"WAVE"));
1725 #if ! JUCE_WAV_DO_NOT_PAD_HEADER_SIZE
1737 output->writeRepeatedByte (0, 28 + (isWaveFmtEx? 0 : 24));
1742 #if JUCE_WAV_DO_NOT_PAD_HEADER_SIZE
1748 output->writeInt64 (riffChunkSize);
1750 output->writeRepeatedByte (0, 12);
1768 output->writeShort ((
short) bytesPerFrame);
1775 output->writeInt (channelMask);
1777 const ExtensibleWavSubFormat& subFormat =
bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;
1779 output->writeInt ((
int) subFormat.data1);
1780 output->writeShort ((
short) subFormat.data2);
1781 output->writeShort ((
short) subFormat.data3);
1782 output->write (subFormat.data4, sizeof (subFormat.data4));
1805 output->writeInt (chunkType);
1811 if (!
data.isEmpty())
1829 auto wavChannelMask = 0;
1831 for (
auto channel : channels)
1833 int wavChannelBit =
static_cast<int> (channel) - 1;
1834 jassert (wavChannelBit >= 0 && wavChannelBit <= 31);
1836 wavChannelMask |= (1 << wavChannelBit);
1839 return wavChannelMask;
1855 bool readSamples (
int** destSamples,
int numDestChannels,
int startOffsetInDestBuffer,
1856 int64 startSampleInFile,
int numSamples)
override
1868 destSamples, startOffsetInDestBuffer, numDestChannels,
1908 for (
int i = 0;
i < numChannelsToRead; ++
i)
1929 template <
typename SampleType>
1932 for (
int i = 0;
i < numChannelsToRead; ++
i)
1945 return { 8000, 11025, 12000, 16000, 22050, 32000, 44100,
1946 48000, 88200, 96000, 176400, 192000, 352800, 384000 };
1951 return { 8, 16, 24, 32 };
1966 for (
auto channel : channelTypes)
1977 #if JUCE_USE_OGGVORBIS
1978 if (
r->isSubformatOggVorbis)
1981 return OggVorbisAudioFormat().createReaderFor (sourceStream, deleteStreamIfOpeningFails);
1985 if (
r->sampleRate > 0 &&
r->numChannels > 0 &&
r->bytesPerFrame > 0 &&
r->bitsPerSample <= 32)
1988 if (! deleteStreamIfOpeningFails)
2013 unsigned int numChannels,
int bitsPerSample,
2017 bitsPerSample, metadataValues, qualityOptionIndex);
2029 (
unsigned int) bitsPerSample, metadataValues);
2041 std::unique_ptr<AudioFormatReader> reader (wav.
createReaderFor (
file.createInputStream().release(),
true));
2043 if (reader !=
nullptr)
2047 if (outStream !=
nullptr)
2049 std::unique_ptr<AudioFormatWriter> writer (wav.
createWriterFor (outStream.get(), reader->sampleRate,
2050 reader->numChannels, (
int) reader->bitsPerSample,
2053 if (writer !=
nullptr)
2055 outStream.release();
2057 bool ok = writer->writeFromAudioReader (*reader, 0, -1);
2076 if (reader !=
nullptr)
2078 auto bwavPos = reader->bwavChunkStart;
2079 auto bwavSize = reader->bwavSize;
2084 auto chunk = BWAVChunk::createFrom (
toMap (newMetadata));
2086 if (chunk.getSize() <= (
size_t) bwavSize)
2089 auto oldSize = wavFile.
getSize();
2096 out.setPosition (bwavPos);
2098 out.setPosition (oldSize);
2108 return slowCopyWavFileWithNewMetadata (wavFile, newMetadata);
2116struct WaveAudioFormatTests :
public UnitTest
2118 WaveAudioFormatTests()
2122 void runTest()
override
2124 beginTest (
"Setting up metadata");
2126 auto metadataValues = toMap (WavAudioFormat::createBWAVMetadata (
"description",
2129 Time::getCurrentTime(),
2130 numTestAudioBufferSamples,
2133 for (
int i = numElementsInArray (WavFileHelpers::ListInfoChunk::types); --
i >= 0;)
2134 metadataValues[WavFileHelpers::ListInfoChunk::types[
i]] = WavFileHelpers::ListInfoChunk::types[
i];
2136 metadataValues[WavAudioFormat::internationalStandardRecordingCode] = WavAudioFormat::internationalStandardRecordingCode;
2138 if (metadataValues.size() > 0)
2139 metadataValues[
"MetaDataSource"] =
"WAV";
2141 const auto smplMetadata = createDefaultSMPLMetadata();
2142 metadataValues.insert (smplMetadata.cbegin(), smplMetadata.cend());
2147 StringPairArray metadataArray;
2148 metadataArray.addUnorderedMap (metadataValues);
2151 beginTest (
"Metadata can be written and read");
2153 const auto newMetadata = getMetadataAfterReading (
format, writeToBlock (
format, metadataArray));
2154 expect (newMetadata == metadataArray,
"Somehow, the metadata is different!");
2158 beginTest (
"Files containing a riff info source and an empty ISRC associate the source with the riffInfoSource key");
2159 StringPairArray meta;
2160 meta.addMap ({ { WavAudioFormat::riffInfoSource,
"customsource" },
2161 { WavAudioFormat::internationalStandardRecordingCode,
"" } });
2162 const auto mb = writeToBlock (
format, meta);
2163 checkPatternsPresent (mb, {
"INFOISRC" });
2164 checkPatternsNotPresent (mb, {
"ISRC:",
"<ebucore" });
2165 const auto a = getMetadataAfterReading (
format, mb);
2166 expect (
a[WavAudioFormat::riffInfoSource] ==
"customsource");
2167 expect (
a[WavAudioFormat::internationalStandardRecordingCode] ==
"");
2171 beginTest (
"Files containing a riff info source and no ISRC associate the source with both keys "
2172 "for backwards compatibility");
2173 StringPairArray meta;
2174 meta.addMap ({ { WavAudioFormat::riffInfoSource,
"customsource" } });
2175 const auto mb = writeToBlock (
format, meta);
2176 checkPatternsPresent (mb, {
"INFOISRC",
"ISRC:customsource",
"<ebucore" });
2177 const auto a = getMetadataAfterReading (
format, mb);
2178 expect (
a[WavAudioFormat::riffInfoSource] ==
"customsource");
2179 expect (
a[WavAudioFormat::internationalStandardRecordingCode] ==
"customsource");
2183 beginTest (
"Files containing an ISRC associate the value with the internationalStandardRecordingCode key "
2184 "and the riffInfoSource key for backwards compatibility");
2185 StringPairArray meta;
2186 meta.addMap ({ { WavAudioFormat::internationalStandardRecordingCode,
"AABBBCCDDDDD" } });
2187 const auto mb = writeToBlock (
format, meta);
2188 checkPatternsPresent (mb, {
"ISRC:AABBBCCDDDDD",
"<ebucore" });
2189 checkPatternsNotPresent (mb, {
"INFOISRC" });
2190 const auto a = getMetadataAfterReading (
format, mb);
2191 expect (
a[WavAudioFormat::riffInfoSource] ==
"AABBBCCDDDDD");
2192 expect (
a[WavAudioFormat::internationalStandardRecordingCode] ==
"AABBBCCDDDDD");
2196 beginTest (
"Files containing an ISRC and a riff info source associate the values with the appropriate keys");
2197 StringPairArray meta;
2198 meta.addMap ({ { WavAudioFormat::riffInfoSource,
"source" } });
2199 meta.addMap ({ { WavAudioFormat::internationalStandardRecordingCode,
"UUVVVXXYYYYY" } });
2200 const auto mb = writeToBlock (
format, meta);
2201 checkPatternsPresent (mb, {
"INFOISRC",
"ISRC:UUVVVXXYYYYY",
"<ebucore" });
2202 const auto a = getMetadataAfterReading (
format, mb);
2203 expect (
a[WavAudioFormat::riffInfoSource] ==
"source");
2204 expect (
a[WavAudioFormat::internationalStandardRecordingCode] ==
"UUVVVXXYYYYY");
2208 beginTest (
"Files containing ASWG metadata read and write correctly");
2210 StringPairArray meta;
2212 for (
const auto&
key : WavFileHelpers::IXMLChunk::aswgMetadataKeys)
2213 meta.set (
key,
"Test123&<>");
2216 auto writer =
rawToUniquePtr (WavAudioFormat().createWriterFor (
new MemoryOutputStream (block,
false), 48000, 1, 32, meta, 0));
2217 expect (writer !=
nullptr);
2222 auto input = std::make_unique<MemoryInputStream> (block,
false);
2224 while (! input->isExhausted())
2226 char chunkType[4] {};
2227 auto pos = input->getPosition();
2229 input->read (chunkType, 4);
2231 if (memcmp (chunkType,
"iXML", 4) == 0)
2235 MemoryBlock xmlBlock;
2236 input->readIntoMemoryBlock (xmlBlock, (ssize_t)
length);
2241 input->setPosition (pos + 1);
2248 auto reader =
rawToUniquePtr (WavAudioFormat().createReaderFor (
new MemoryInputStream (block,
false),
true));
2249 expect (reader !=
nullptr);
2251 for (
const auto&
key : meta.getAllKeys())
2253 const auto oldValue = meta.getValue (
key,
"!");
2254 const auto newValue = reader->metadataValues.getValue (
key,
"");
2255 expectEquals (oldValue, newValue);
2258 expect (reader->metadataValues.getValue (WavAudioFormat::aswgVersion,
"") ==
"3.01");
2264 MemoryBlock writeToBlock (WavAudioFormat&
format, StringPairArray meta)
2273 numTestAudioBufferChannels,
2277 expect (writer !=
nullptr);
2278 AudioBuffer<float>
buffer (numTestAudioBufferChannels, numTestAudioBufferSamples);
2279 expect (writer->writeFromAudioSampleBuffer (buffer, 0, numTestAudioBufferSamples));
2285 StringPairArray getMetadataAfterReading (WavAudioFormat&
format,
const MemoryBlock& mb)
2287 auto reader =
rawToUniquePtr (
format.createReaderFor (
new MemoryInputStream (mb,
false),
true));
2288 expect (reader !=
nullptr);
2289 return reader->metadataValues;
2292 template <
typename Fn>
2293 void checkPatterns (
const MemoryBlock& mb,
const std::vector<std::string>& patterns, Fn&&
fn)
2295 for (
const auto&
pattern : patterns)
2297 const auto begin =
static_cast<const char*
> (mb.
getData());
2299 expect (
fn (std::search (begin, end,
pattern.begin(),
pattern.end()), end));
2303 void checkPatternsPresent (
const MemoryBlock& mb,
const std::vector<std::string>& patterns)
2305 checkPatterns (mb, patterns, std::not_equal_to<>{});
2308 void checkPatternsNotPresent (
const MemoryBlock& mb,
const std::vector<std::string>& patterns)
2310 checkPatterns (mb, patterns, std::equal_to<>{});
2315 numTestAudioBufferChannels = 2,
2316 numTestAudioBufferSamples = 256
2319 static StringMap createDefaultSMPLMetadata()
2323 m[
"Manufacturer"] =
"0";
2325 m[
"SamplePeriod"] =
"0";
2326 m[
"MidiUnityNote"] =
"60";
2327 m[
"MidiPitchFraction"] =
"0";
2328 m[
"SmpteFormat"] =
"0";
2329 m[
"SmpteOffset"] =
"0";
2330 m[
"NumSampleLoops"] =
"0";
2331 m[
"SamplerData"] =
"0";
2339static const WaveAudioFormatTests waveAudioFormatTests;
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
uint8_t a
Definition Spc_Cpu.h:141
goto loop
Definition Spc_Cpu.h:155
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
uint32_t uint32
Definition basics.h:90
static const unsigned long mask[]
Definition bitwise.c:31
static uint32 littleEndianInt(const void *bytes) noexcept
Definition ByteOrder.h:236
static uint16 swap(uint16 value) noexcept
Definition ByteOrder.h:151
static uint16 swapIfBigEndian(uint16 value) noexcept
Definition ByteOrder.h:218
Definition MemoryBlock.h:39
size_t getSize() const noexcept
Definition MemoryBlock.h:102
void * getData() const noexcept
Definition MemoryBlock.h:91
String toString() const
Definition MemoryBlock.cpp:263
static String createStringFromData(const void *data, int size)
Definition String.cpp:1721
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Definition String.cpp:1961
Definition juce_Array.h:56
void add(const ElementType &newElement)
Definition juce_Array.h:418
bool contains(ParameterType elementToLookFor) const
Definition juce_Array.h:400
Definition juce_AudioChannelSet.h:47
static AudioChannelSet JUCE_CALLTYPE quadraphonic()
Definition juce_AudioChannelSet.cpp:466
static AudioChannelSet JUCE_CALLTYPE create5point0()
Definition juce_AudioChannelSet.cpp:456
int size() const noexcept
Definition juce_AudioChannelSet.cpp:396
bool isDiscreteLayout() const noexcept
Definition juce_AudioChannelSet.cpp:387
static AudioChannelSet JUCE_CALLTYPE mono()
Definition juce_AudioChannelSet.cpp:451
static AudioChannelSet JUCE_CALLTYPE stereo()
Definition juce_AudioChannelSet.cpp:452
ChannelType
Definition juce_AudioChannelSet.h:317
@ topRearRight
Definition juce_AudioChannelSet.h:341
@ discreteChannel0
Definition juce_AudioChannelSet.h:423
void addChannel(ChannelType newChannelType)
Definition juce_AudioChannelSet.cpp:436
static AudioChannelSet JUCE_CALLTYPE create5point1()
Definition juce_AudioChannelSet.cpp:457
static AudioChannelSet JUCE_CALLTYPE create7point0SDDS()
Definition juce_AudioChannelSet.cpp:463
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS()
Definition juce_AudioChannelSet.cpp:465
static AudioChannelSet JUCE_CALLTYPE canonicalChannelSet(int numChannels)
Definition juce_AudioChannelSet.cpp:511
static AudioChannelSet JUCE_CALLTYPE discreteChannels(int numChannels)
Definition juce_AudioChannelSet.cpp:504
static AudioChannelSet JUCE_CALLTYPE createLCR()
Definition juce_AudioChannelSet.cpp:453
Array< ChannelType > getChannelTypes() const
Definition juce_AudioChannelSet.cpp:426
Definition juce_BigInteger.h:39
int findNextSetBit(int startIndex) const noexcept
Definition juce_BigInteger.cpp:387
static Type swapIfBigEndian(Type value) noexcept
Definition juce_ByteOrder.h:67
static juce_wchar toUpperCase(juce_wchar character) noexcept
Definition juce_CharacterFunctions.cpp:28
Definition juce_File.h:45
std::unique_ptr< FileOutputStream > createOutputStream(size_t bufferSize=0x8000) const
Definition juce_File.cpp:734
int64 getSize() const
Definition juce_posix_SharedCode.h:257
std::unique_ptr< FileInputStream > createInputStream() const
Definition juce_File.cpp:724
Definition juce_FileOutputStream.h:35
Definition juce_HeapBlock.h:87
void calloc(SizeType newNumElements, const size_t elementSize=sizeof(ElementType))
Definition juce_HeapBlock.h:263
Definition juce_MemoryBlock.h:33
void * getData() noexcept
Definition juce_MemoryBlock.h:91
String toString() const
Definition juce_MemoryBlock.cpp:265
size_t getSize() const noexcept
Definition juce_MemoryBlock.h:127
Definition juce_WavAudioFormat.cpp:1847
void readMaxLevels(int64 startSampleInFile, int64 numSamples, Range< float > *results, int numChannelsToRead) override
Definition juce_WavAudioFormat.cpp:1900
void scanMinAndMax(int64 startSampleInFile, int64 numSamples, Range< float > *results, int numChannelsToRead) const noexcept
Definition juce_WavAudioFormat.cpp:1930
void getSample(int64 sample, float *result) const noexcept override
Definition juce_WavAudioFormat.cpp:1873
MemoryMappedWavReader(const File &wavFile, const WavAudioFormatReader &reader)
Definition juce_WavAudioFormat.cpp:1849
bool readSamples(int **destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override
Definition juce_WavAudioFormat.cpp:1855
Definition juce_MemoryOutputStream.h:36
size_t getDataSize() const noexcept
Definition juce_MemoryOutputStream.h:80
bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat) override
Definition juce_MemoryOutputStream.cpp:118
MemoryBlock getMemoryBlock() const
Definition juce_MemoryOutputStream.cpp:143
Definition juce_OutputStream.h:38
Definition juce_Range.h:40
Definition juce_String.h:53
Definition juce_StringPairArray.h:35
const StringArray & getAllValues() const noexcept
Definition juce_StringPairArray.h:90
int size() const noexcept
Definition juce_StringPairArray.h:93
const StringArray & getAllKeys() const noexcept
Definition juce_StringPairArray.h:87
Definition juce_StringRef.h:62
Definition juce_TemporaryFile.h:65
bool overwriteTargetFileWithTemporary() const
Definition juce_TemporaryFile.cpp:93
const File & getFile() const noexcept
Definition juce_TemporaryFile.h:126
Definition juce_Time.h:37
String formatted(const String &format) const
Definition juce_Time.cpp:341
Definition juce_UnitTest.h:70
Definition juce_XmlElement.h:83
void addChildElement(XmlElement *newChildElement) noexcept
Definition juce_XmlElement.cpp:700
void writeTo(OutputStream &output, const TextFormat &format={}) const
Definition juce_XmlElement.cpp:359
unsigned * m
Definition inflate.c:1559
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned x[BMAX+1]
Definition inflate.c:1586
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
virtual ASIOError start()=0
int val
Definition jpeglib.h:956
JSAMPIMAGE data
Definition jpeglib.h:945
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
#define offsetof(TYPE, MEMBER)
Definition list.h:42
Definition juce_UnitTestCategories.h:27
Definition juce_WavAudioFormat.cpp:1104
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:1133
static void addToMetadata(StringMap &destValues, const String &source)
Definition juce_WavAudioFormat.cpp:1105
Definition juce_WavAudioFormat.cpp:953
static const std::unordered_set< String > aswgMetadataKeys
Definition juce_WavAudioFormat.cpp:955
static void addToMetadata(StringMap &destValues, const String &source)
Definition juce_WavAudioFormat.cpp:1041
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:1064
Definition juce_WavAudioFormat.cpp:601
static void appendExtraChunk(const StringMap &values, const String &prefix, MemoryOutputStream &out)
Definition juce_WavAudioFormat.cpp:628
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:650
static int getValue(const StringMap &values, const String &name)
Definition juce_WavAudioFormat.cpp:602
static void appendLabelOrNoteChunk(const StringMap &values, const String &prefix, const int chunkType, MemoryOutputStream &out)
Definition juce_WavAudioFormat.cpp:612
Definition juce_WavAudioFormat.cpp:679
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:823
static const char *const types[]
Definition juce_WavAudioFormat.cpp:680
static bool writeValue(const StringMap &values, MemoryOutputStream &out, const char *paramName)
Definition juce_WavAudioFormat.cpp:803
static bool isMatchingTypeIgnoringCase(const int value, const char *const name) noexcept
Definition juce_WavAudioFormat.cpp:765
static void addToMetadata(StringMap &values, InputStream &input, int64 chunkEnd)
Definition juce_WavAudioFormat.cpp:774
Definition juce_WavAudioFormat.cpp:262
AudioChannelSet canonicalWavChannelSet(int numChannels)
Definition juce_WavAudioFormat.cpp:337
static const ExtensibleWavSubFormat pcmFormat
Definition juce_WavAudioFormat.cpp:1186
constexpr size_t roundUpSize(size_t sz) noexcept
Definition juce_WavAudioFormat.cpp:264
static const ExtensibleWavSubFormat IEEEFloatFormat
Definition juce_WavAudioFormat.cpp:1187
static const ExtensibleWavSubFormat ambisonicFormat
Definition juce_WavAudioFormat.cpp:1188
constexpr int chunkName(const char *name) noexcept
Definition juce_WavAudioFormat.cpp:263
struct juce::WavFileHelpers::BWAVChunk JUCE_PACKED
static bool slowCopyWavFileWithNewMetadata(const File &file, const StringPairArray &metadata)
Definition juce_WavAudioFormat.cpp:2036
JOCTET * buffer
Definition juce_JPEGLoader.cpp:302
Definition carla_juce.cpp:31
void zerostruct(Type &structure) noexcept
Definition juce_Memory.h:32
static const char *const wavFormatName
Definition juce_WavAudioFormat.cpp:47
std::unordered_map< String, String > StringMap
Definition juce_WavAudioFormat.cpp:29
static auto toMap(const StringPairArray &array)
Definition juce_WavAudioFormat.cpp:31
unsigned short uint16
Definition juce_MathsFunctions.h:41
unsigned long long uint64
Definition juce_MathsFunctions.h:56
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
class JUCE_API juce::PixelARGB JUCE_PACKED
unsigned int uint32
Definition juce_MathsFunctions.h:45
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94
RangedDirectoryIterator end(const RangedDirectoryIterator &)
Definition juce_RangedDirectoryIterator.h:184
static auto getValueWithDefault(const StringMap &m, const String &key, const String &fallback={})
Definition juce_WavAudioFormat.cpp:41
long long int64
Definition juce_MathsFunctions.h:54
wchar_t juce_wchar
Definition juce_CharacterFunctions.h:42
std::unique_ptr< XmlElement > parseXML(const String &textToParse)
Definition juce_XmlDocument.cpp:41
signed char int8
Definition juce_MathsFunctions.h:35
unsigned char uint8
Definition juce_MathsFunctions.h:37
@ label
Definition juce_AccessibilityRole.h:44
RangedDirectoryIterator begin(const RangedDirectoryIterator &it)
Definition juce_RangedDirectoryIterator.h:179
std::unique_ptr< T > rawToUniquePtr(T *ptr)
Definition juce_Memory.h:195
void zeromem(void *memory, size_t numBytes) noexcept
Definition juce_Memory.h:28
png_uint_32 length
Definition png.c:2247
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:870
uint16 rootNote
Definition juce_WavAudioFormat.cpp:921
uint16 meterNumerator
Definition juce_WavAudioFormat.cpp:926
MemoryBlock toMemoryBlock() const
Definition juce_WavAudioFormat.cpp:875
AcidChunk(InputStream &input, size_t length)
Definition juce_WavAudioFormat.cpp:841
static uint32 getFlagIfPresent(const StringMap &values, const char *name, uint32 flag)
Definition juce_WavAudioFormat.cpp:903
static float swapFloatByteOrder(const float x) noexcept
Definition juce_WavAudioFormat.cpp:908
AcidChunk(const StringMap &values)
Definition juce_WavAudioFormat.cpp:847
void setBoolFlag(StringMap &values, const char *name, uint32 mask) const
Definition juce_WavAudioFormat.cpp:898
uint32 numBeats
Definition juce_WavAudioFormat.cpp:924
void addToMetadata(StringMap &values) const
Definition juce_WavAudioFormat.cpp:881
float reserved2
Definition juce_WavAudioFormat.cpp:923
float tempo
Definition juce_WavAudioFormat.cpp:927
uint16 reserved1
Definition juce_WavAudioFormat.cpp:922
uint32 flags
Definition juce_WavAudioFormat.cpp:920
uint16 meterDenominator
Definition juce_WavAudioFormat.cpp:925
Definition juce_WavAudioFormat.cpp:271
uint8 reserved[190]
Definition juce_WavAudioFormat.cpp:281
char codingHistory[1]
Definition juce_WavAudioFormat.cpp:282
char originator[32]
Definition juce_WavAudioFormat.cpp:273
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:300
char description[256]
Definition juce_WavAudioFormat.cpp:272
uint8 umid[64]
Definition juce_WavAudioFormat.cpp:280
uint32 timeRefHigh
Definition juce_WavAudioFormat.cpp:278
uint32 timeRefLow
Definition juce_WavAudioFormat.cpp:277
uint16 version
Definition juce_WavAudioFormat.cpp:279
char originationDate[10]
Definition juce_WavAudioFormat.cpp:275
char originatorRef[32]
Definition juce_WavAudioFormat.cpp:274
char originationTime[8]
Definition juce_WavAudioFormat.cpp:276
void copyTo(StringMap &values, const int totalSize) const
Definition juce_WavAudioFormat.cpp:284
Definition juce_WavAudioFormat.cpp:516
uint32 chunkStart
Definition juce_WavAudioFormat.cpp:520
uint32 blockStart
Definition juce_WavAudioFormat.cpp:521
uint32 order
Definition juce_WavAudioFormat.cpp:518
uint32 chunkID
Definition juce_WavAudioFormat.cpp:519
uint32 identifier
Definition juce_WavAudioFormat.cpp:517
uint32 offset
Definition juce_WavAudioFormat.cpp:522
Definition juce_WavAudioFormat.cpp:514
Cue cues[1]
Definition juce_WavAudioFormat.cpp:526
static void setValue(StringMap &values, int prefix, const char *name, uint32 val)
Definition juce_WavAudioFormat.cpp:528
uint32 numCues
Definition juce_WavAudioFormat.cpp:525
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:551
void copyTo(StringMap &values, const int totalSize) const
Definition juce_WavAudioFormat.cpp:533
Definition juce_WavAudioFormat.cpp:1191
uint32 sampleCountLow
Definition juce_WavAudioFormat.cpp:1196
uint32 tableLength
Definition juce_WavAudioFormat.cpp:1198
uint32 dataSizeLow
Definition juce_WavAudioFormat.cpp:1194
uint32 dataSizeHigh
Definition juce_WavAudioFormat.cpp:1195
uint32 sampleCountHigh
Definition juce_WavAudioFormat.cpp:1197
uint32 riffSizeLow
Definition juce_WavAudioFormat.cpp:1192
uint32 riffSizeHigh
Definition juce_WavAudioFormat.cpp:1193
Definition juce_WavAudioFormat.cpp:459
int8 lowVelocity
Definition juce_WavAudioFormat.cpp:465
void copyTo(StringMap &values) const
Definition juce_WavAudioFormat.cpp:473
int8 highNote
Definition juce_WavAudioFormat.cpp:464
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:489
int8 baseNote
Definition juce_WavAudioFormat.cpp:460
static void setValue(StringMap &values, const char *name, int val)
Definition juce_WavAudioFormat.cpp:468
int8 detune
Definition juce_WavAudioFormat.cpp:461
int8 highVelocity
Definition juce_WavAudioFormat.cpp:466
int8 lowNote
Definition juce_WavAudioFormat.cpp:463
int8 gain
Definition juce_WavAudioFormat.cpp:462
static int8 getValue(const StringMap &values, const char *name, const char *def)
Definition juce_WavAudioFormat.cpp:484
Definition juce_WavAudioFormat.cpp:355
uint32 type
Definition juce_WavAudioFormat.cpp:357
uint32 end
Definition juce_WavAudioFormat.cpp:359
uint32 fraction
Definition juce_WavAudioFormat.cpp:360
uint32 identifier
Definition juce_WavAudioFormat.cpp:356
uint32 playCount
Definition juce_WavAudioFormat.cpp:361
uint32 start
Definition juce_WavAudioFormat.cpp:358
Definition juce_WavAudioFormat.cpp:353
uint32 product
Definition juce_WavAudioFormat.cpp:365
static void setValue(StringMap &values, int prefix, const char *name, uint32 val)
Definition juce_WavAudioFormat.cpp:381
void copyTo(StringMap &values, const int totalSize) const
Definition juce_WavAudioFormat.cpp:386
uint32 samplePeriod
Definition juce_WavAudioFormat.cpp:366
static uint32 getValue(const StringMap &values, int prefix, const char *name, const char *def)
Definition juce_WavAudioFormat.cpp:418
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:423
uint32 manufacturer
Definition juce_WavAudioFormat.cpp:364
uint32 smpteOffset
Definition juce_WavAudioFormat.cpp:370
uint32 numSampleLoops
Definition juce_WavAudioFormat.cpp:371
static uint32 getValue(const StringMap &values, NameType name, const char *def)
Definition juce_WavAudioFormat.cpp:413
uint32 midiUnityNote
Definition juce_WavAudioFormat.cpp:367
uint32 samplerData
Definition juce_WavAudioFormat.cpp:372
uint32 smpteFormat
Definition juce_WavAudioFormat.cpp:369
SampleLoop loops[1]
Definition juce_WavAudioFormat.cpp:373
static void setValue(StringMap &values, NameType name, uint32 val)
Definition juce_WavAudioFormat.cpp:376
uint32 midiPitchFraction
Definition juce_WavAudioFormat.cpp:368
Definition juce_WavAudioFormat.cpp:933
static MemoryBlock createFrom(const StringMap &values)
Definition juce_WavAudioFormat.cpp:934
const char const char const char const char char * fn
Definition swell-functions.h:168
const char * text
Definition swell-functions.h:167
signed int sample
Definition tap_dynamics_m.c:41
int n
Definition crypt.c:458
return c
Definition crypt.c:175
ZCONST char * key
Definition crypt.c:587
int r
Definition crypt.c:458
int * pattern
Definition match.c:126
int result
Definition process.c:1455
int flag
Definition unix.c:754
typedef int(UZ_EXP MsgFn)()
struct zdirent * file
Definition win32.c:1500
_WDL_CSTRING_PREFIX void INT_PTR const char * format
Definition wdlcstring.h:263