LMMS
Loading...
Searching...
No Matches
juce_WavAudioFormat.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29using StringMap = std::unordered_map<String, String>;
30
31static auto toMap (const StringPairArray& array)
32{
34
35 for (auto i = 0; i < array.size(); ++i)
36 result[array.getAllKeys()[i]] = array.getAllValues()[i];
37
38 return result;
39}
40
41static auto getValueWithDefault (const StringMap& m, const String& key, const String& fallback = {})
42{
43 const auto iter = m.find (key);
44 return iter != m.cend() ? iter->second : fallback;
45}
46
47static const char* const wavFormatName = "WAV file";
48
49//==============================================================================
50const char* const WavAudioFormat::bwavDescription = "bwav description";
51const char* const WavAudioFormat::bwavOriginator = "bwav originator";
52const char* const WavAudioFormat::bwavOriginatorRef = "bwav originator ref";
53const char* const WavAudioFormat::bwavOriginationDate = "bwav origination date";
54const char* const WavAudioFormat::bwavOriginationTime = "bwav origination time";
55const char* const WavAudioFormat::bwavTimeReference = "bwav time reference";
56const char* const WavAudioFormat::bwavCodingHistory = "bwav coding history";
57
59 const String& originator,
60 const String& originatorRef,
61 Time date,
62 int64 timeReferenceSamples,
63 const String& codingHistory)
64{
66
67 m.set (bwavDescription, description);
68 m.set (bwavOriginator, originator);
69 m.set (bwavOriginatorRef, originatorRef);
70 m.set (bwavOriginationDate, date.formatted ("%Y-%m-%d"));
71 m.set (bwavOriginationTime, date.formatted ("%H:%M:%S"));
72 m.set (bwavTimeReference, String (timeReferenceSamples));
73 m.set (bwavCodingHistory, codingHistory);
74
75 return m;
76}
77
78const char* const WavAudioFormat::acidOneShot = "acid one shot";
79const char* const WavAudioFormat::acidRootSet = "acid root set";
80const char* const WavAudioFormat::acidStretch = "acid stretch";
81const char* const WavAudioFormat::acidDiskBased = "acid disk based";
82const char* const WavAudioFormat::acidizerFlag = "acidizer flag";
83const char* const WavAudioFormat::acidRootNote = "acid root note";
84const char* const WavAudioFormat::acidBeats = "acid beats";
85const char* const WavAudioFormat::acidDenominator = "acid denominator";
86const char* const WavAudioFormat::acidNumerator = "acid numerator";
87const char* const WavAudioFormat::acidTempo = "acid tempo";
88
89const char* const WavAudioFormat::riffInfoArchivalLocation = "IARL";
90const char* const WavAudioFormat::riffInfoArtist = "IART";
91const char* const WavAudioFormat::riffInfoBaseURL = "IBSU";
92const char* const WavAudioFormat::riffInfoCinematographer = "ICNM";
93const char* const WavAudioFormat::riffInfoComment = "CMNT";
94const char* const WavAudioFormat::riffInfoComment2 = "ICMT";
95const char* const WavAudioFormat::riffInfoComments = "COMM";
96const char* const WavAudioFormat::riffInfoCommissioned = "ICMS";
97const char* const WavAudioFormat::riffInfoCopyright = "ICOP";
98const char* const WavAudioFormat::riffInfoCostumeDesigner = "ICDS";
99const char* const WavAudioFormat::riffInfoCountry = "ICNT";
100const char* const WavAudioFormat::riffInfoCropped = "ICRP";
101const char* const WavAudioFormat::riffInfoDateCreated = "ICRD";
102const char* const WavAudioFormat::riffInfoDateTimeOriginal = "IDIT";
103const char* const WavAudioFormat::riffInfoDefaultAudioStream = "ICAS";
104const char* const WavAudioFormat::riffInfoDimension = "IDIM";
105const char* const WavAudioFormat::riffInfoDirectory = "DIRC";
106const char* const WavAudioFormat::riffInfoDistributedBy = "IDST";
107const char* const WavAudioFormat::riffInfoDotsPerInch = "IDPI";
108const char* const WavAudioFormat::riffInfoEditedBy = "IEDT";
109const char* const WavAudioFormat::riffInfoEighthLanguage = "IAS8";
110const char* const WavAudioFormat::riffInfoEncodedBy = "CODE";
111const char* const WavAudioFormat::riffInfoEndTimecode = "TCDO";
112const char* const WavAudioFormat::riffInfoEngineer = "IENG";
113const char* const WavAudioFormat::riffInfoFifthLanguage = "IAS5";
114const char* const WavAudioFormat::riffInfoFirstLanguage = "IAS1";
115const char* const WavAudioFormat::riffInfoFourthLanguage = "IAS4";
116const char* const WavAudioFormat::riffInfoGenre = "GENR";
117const char* const WavAudioFormat::riffInfoKeywords = "IKEY";
118const char* const WavAudioFormat::riffInfoLanguage = "LANG";
119const char* const WavAudioFormat::riffInfoLength = "TLEN";
120const char* const WavAudioFormat::riffInfoLightness = "ILGT";
121const char* const WavAudioFormat::riffInfoLocation = "LOCA";
122const char* const WavAudioFormat::riffInfoLogoIconURL = "ILIU";
123const char* const WavAudioFormat::riffInfoLogoURL = "ILGU";
124const char* const WavAudioFormat::riffInfoMedium = "IMED";
125const char* const WavAudioFormat::riffInfoMoreInfoBannerImage = "IMBI";
126const char* const WavAudioFormat::riffInfoMoreInfoBannerURL = "IMBU";
127const char* const WavAudioFormat::riffInfoMoreInfoText = "IMIT";
128const char* const WavAudioFormat::riffInfoMoreInfoURL = "IMIU";
129const char* const WavAudioFormat::riffInfoMusicBy = "IMUS";
130const char* const WavAudioFormat::riffInfoNinthLanguage = "IAS9";
131const char* const WavAudioFormat::riffInfoNumberOfParts = "PRT2";
132const char* const WavAudioFormat::riffInfoOrganisation = "TORG";
133const char* const WavAudioFormat::riffInfoPart = "PRT1";
134const char* const WavAudioFormat::riffInfoProducedBy = "IPRO";
135const char* const WavAudioFormat::riffInfoProductName = "IPRD";
136const char* const WavAudioFormat::riffInfoProductionDesigner = "IPDS";
137const char* const WavAudioFormat::riffInfoProductionStudio = "ISDT";
138const char* const WavAudioFormat::riffInfoRate = "RATE";
139const char* const WavAudioFormat::riffInfoRated = "AGES";
140const char* const WavAudioFormat::riffInfoRating = "IRTD";
141const char* const WavAudioFormat::riffInfoRippedBy = "IRIP";
142const char* const WavAudioFormat::riffInfoSecondaryGenre = "ISGN";
143const char* const WavAudioFormat::riffInfoSecondLanguage = "IAS2";
144const char* const WavAudioFormat::riffInfoSeventhLanguage = "IAS7";
145const char* const WavAudioFormat::riffInfoSharpness = "ISHP";
146const char* const WavAudioFormat::riffInfoSixthLanguage = "IAS6";
147const char* const WavAudioFormat::riffInfoSoftware = "ISFT";
148const char* const WavAudioFormat::riffInfoSoundSchemeTitle = "DISP";
149const char* const WavAudioFormat::riffInfoSource = "ISRC";
150const char* const WavAudioFormat::riffInfoSourceFrom = "ISRF";
151const char* const WavAudioFormat::riffInfoStarring_ISTR = "ISTR";
152const char* const WavAudioFormat::riffInfoStarring_STAR = "STAR";
153const char* const WavAudioFormat::riffInfoStartTimecode = "TCOD";
154const char* const WavAudioFormat::riffInfoStatistics = "STAT";
155const char* const WavAudioFormat::riffInfoSubject = "ISBJ";
156const char* const WavAudioFormat::riffInfoTapeName = "TAPE";
157const char* const WavAudioFormat::riffInfoTechnician = "ITCH";
158const char* const WavAudioFormat::riffInfoThirdLanguage = "IAS3";
159const char* const WavAudioFormat::riffInfoTimeCode = "ISMP";
160const char* const WavAudioFormat::riffInfoTitle = "INAM";
161const char* const WavAudioFormat::riffInfoTrackNo = "IPRT";
162const char* const WavAudioFormat::riffInfoTrackNumber = "TRCK";
163const char* const WavAudioFormat::riffInfoURL = "TURL";
164const char* const WavAudioFormat::riffInfoVegasVersionMajor = "VMAJ";
165const char* const WavAudioFormat::riffInfoVegasVersionMinor = "VMIN";
166const char* const WavAudioFormat::riffInfoVersion = "TVER";
167const char* const WavAudioFormat::riffInfoWatermarkURL = "IWMU";
168const char* const WavAudioFormat::riffInfoWrittenBy = "IWRI";
169const char* const WavAudioFormat::riffInfoYear = "YEAR";
170
171const char* const WavAudioFormat::aswgContentType = "contentType";
172const char* const WavAudioFormat::aswgProject = "project";
173const char* const WavAudioFormat::aswgOriginator = "originator";
174const char* const WavAudioFormat::aswgOriginatorStudio = "originatorStudio";
175const char* const WavAudioFormat::aswgNotes = "notes";
176const char* const WavAudioFormat::aswgSession = "session";
177const char* const WavAudioFormat::aswgState = "state";
178const char* const WavAudioFormat::aswgEditor = "editor";
179const char* const WavAudioFormat::aswgMixer = "mixer";
180const char* const WavAudioFormat::aswgFxChainName = "fxChainName";
181const char* const WavAudioFormat::aswgChannelConfig = "channelConfig";
182const char* const WavAudioFormat::aswgAmbisonicFormat = "ambisonicFormat";
183const char* const WavAudioFormat::aswgAmbisonicChnOrder = "ambisonicChnOrder";
184const char* const WavAudioFormat::aswgAmbisonicNorm = "ambisonicNorm";
185const char* const WavAudioFormat::aswgMicType = "micType";
186const char* const WavAudioFormat::aswgMicConfig = "micConfig";
187const char* const WavAudioFormat::aswgMicDistance = "micDistance";
188const char* const WavAudioFormat::aswgRecordingLoc = "recordingLoc";
189const char* const WavAudioFormat::aswgIsDesigned = "isDesigned";
190const char* const WavAudioFormat::aswgRecEngineer = "recEngineer";
191const char* const WavAudioFormat::aswgRecStudio = "recStudio";
192const char* const WavAudioFormat::aswgImpulseLocation = "impulseLocation";
193const char* const WavAudioFormat::aswgCategory = "category";
194const char* const WavAudioFormat::aswgSubCategory = "subCategory";
195const char* const WavAudioFormat::aswgCatId = "catId";
196const char* const WavAudioFormat::aswgUserCategory = "userCategory";
197const char* const WavAudioFormat::aswgUserData = "userData";
198const char* const WavAudioFormat::aswgVendorCategory = "vendorCategory";
199const char* const WavAudioFormat::aswgFxName = "fxName";
200const char* const WavAudioFormat::aswgLibrary = "library";
201const char* const WavAudioFormat::aswgCreatorId = "creatorId";
202const char* const WavAudioFormat::aswgSourceId = "sourceId";
203const char* const WavAudioFormat::aswgRmsPower = "rmsPower";
204const char* const WavAudioFormat::aswgLoudness = "loudness";
205const char* const WavAudioFormat::aswgLoudnessRange = "loudnessRange";
206const char* const WavAudioFormat::aswgMaxPeak = "maxPeak";
207const char* const WavAudioFormat::aswgSpecDensity = "specDensity";
208const char* const WavAudioFormat::aswgZeroCrossRate = "zeroCrossRate";
209const char* const WavAudioFormat::aswgPapr = "papr";
210const char* const WavAudioFormat::aswgText = "text";
211const char* const WavAudioFormat::aswgEfforts = "efforts";
212const char* const WavAudioFormat::aswgEffortType = "effortType";
213const char* const WavAudioFormat::aswgProjection = "projection";
214const char* const WavAudioFormat::aswgLanguage = "language";
215const char* const WavAudioFormat::aswgTimingRestriction = "timingRestriction";
216const char* const WavAudioFormat::aswgCharacterName = "characterName";
217const char* const WavAudioFormat::aswgCharacterGender = "characterGender";
218const char* const WavAudioFormat::aswgCharacterAge = "characterAge";
219const char* const WavAudioFormat::aswgCharacterRole = "characterRole";
220const char* const WavAudioFormat::aswgActorName = "actorName";
221const char* const WavAudioFormat::aswgActorGender = "actorGender";
222const char* const WavAudioFormat::aswgDirector = "director";
223const char* const WavAudioFormat::aswgDirection = "direction";
224const char* const WavAudioFormat::aswgFxUsed = "fxUsed";
225const char* const WavAudioFormat::aswgUsageRights = "usageRights";
226const char* const WavAudioFormat::aswgIsUnion = "isUnion";
227const char* const WavAudioFormat::aswgAccent = "accent";
228const char* const WavAudioFormat::aswgEmotion = "emotion";
229const char* const WavAudioFormat::aswgComposor = "composor";
230const char* const WavAudioFormat::aswgArtist = "artist";
231const char* const WavAudioFormat::aswgSongTitle = "songTitle";
232const char* const WavAudioFormat::aswgGenre = "genre";
233const char* const WavAudioFormat::aswgSubGenre = "subGenre";
234const char* const WavAudioFormat::aswgProducer = "producer";
235const char* const WavAudioFormat::aswgMusicSup = "musicSup";
236const char* const WavAudioFormat::aswgInstrument = "instrument";
237const char* const WavAudioFormat::aswgMusicPublisher = "musicPublisher";
238const char* const WavAudioFormat::aswgRightsOwner = "rightsOwner";
239const char* const WavAudioFormat::aswgIsSource = "isSource";
240const char* const WavAudioFormat::aswgIsLoop = "isLoop";
241const char* const WavAudioFormat::aswgIntensity = "intensity";
242const char* const WavAudioFormat::aswgIsFinal = "isFinal";
243const char* const WavAudioFormat::aswgOrderRef = "orderRef";
244const char* const WavAudioFormat::aswgIsOst = "isOst";
245const char* const WavAudioFormat::aswgIsCinematic = "isCinematic";
246const char* const WavAudioFormat::aswgIsLicensed = "isLicensed";
247const char* const WavAudioFormat::aswgIsDiegetic = "isDiegetic";
248const char* const WavAudioFormat::aswgMusicVersion = "musicVersion";
249const char* const WavAudioFormat::aswgIsrcId = "isrcId";
250const char* const WavAudioFormat::aswgTempo = "tempo";
251const char* const WavAudioFormat::aswgTimeSig = "timeSig";
252const char* const WavAudioFormat::aswgInKey = "inKey";
253const char* const WavAudioFormat::aswgBillingCode = "billingCode";
254const char* const WavAudioFormat::aswgVersion = "IXML_VERSION";
255
256const char* const WavAudioFormat::ISRC = "ISRC";
257const char* const WavAudioFormat::internationalStandardRecordingCode = "international standard recording code";
258const char* const WavAudioFormat::tracktionLoopInfo = "tracktion loop info";
259
260//==============================================================================
262{
263 constexpr inline int chunkName (const char* name) noexcept { return (int) ByteOrder::littleEndianInt (name); }
264 constexpr inline size_t roundUpSize (size_t sz) noexcept { return (sz + 3) & ~3u; }
265
266 #if JUCE_MSVC
267 #pragma pack (push, 1)
268 #endif
269
271 {
272 char description[256];
273 char originator[32];
283
299
300 static MemoryBlock createFrom (const StringMap& values)
301 {
303 data.fillWith (0);
304
305 auto* b = (BWAVChunk*) data.getData();
306
307 // Allow these calls to overwrite an extra byte at the end, which is fine as long
308 // as they get called in the right order.
309 getValueWithDefault (values, WavAudioFormat::bwavDescription) .copyToUTF8 (b->description, 257);
310 getValueWithDefault (values, WavAudioFormat::bwavOriginator) .copyToUTF8 (b->originator, 33);
311 getValueWithDefault (values, WavAudioFormat::bwavOriginatorRef) .copyToUTF8 (b->originatorRef, 33);
312 getValueWithDefault (values, WavAudioFormat::bwavOriginationDate).copyToUTF8 (b->originationDate, 11);
313 getValueWithDefault (values, WavAudioFormat::bwavOriginationTime).copyToUTF8 (b->originationTime, 9);
314
315 auto time = getValueWithDefault (values, WavAudioFormat::bwavTimeReference).getLargeIntValue();
316 b->timeRefLow = ByteOrder::swapIfBigEndian ((uint32) (time & 0xffffffff));
317 b->timeRefHigh = ByteOrder::swapIfBigEndian ((uint32) (time >> 32));
318
319 getValueWithDefault (values, WavAudioFormat::bwavCodingHistory).copyToUTF8 (b->codingHistory, 0x7fffffff);
320
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
326 || time != 0)
327 {
328 return data;
329 }
330
331 return {};
332 }
333
335
336 //==============================================================================
338 {
339 if (numChannels == 1) return AudioChannelSet::mono();
340 if (numChannels == 2) return AudioChannelSet::stereo();
341 if (numChannels == 3) return AudioChannelSet::createLCR();
342 if (numChannels == 4) return AudioChannelSet::quadraphonic();
343 if (numChannels == 5) return AudioChannelSet::create5point0();
344 if (numChannels == 6) return AudioChannelSet::create5point1();
345 if (numChannels == 7) return AudioChannelSet::create7point0SDDS();
346 if (numChannels == 8) return AudioChannelSet::create7point1SDDS();
347
348 return AudioChannelSet::discreteChannels (numChannels);
349 }
350
351 //==============================================================================
353 {
363
374
375 template <typename NameType>
376 static void setValue (StringMap& values, NameType name, uint32 val)
377 {
379 }
380
381 static void setValue (StringMap& values, int prefix, const char* name, uint32 val)
382 {
383 setValue (values, "Loop" + String (prefix) + name, val);
384 }
385
386 void copyTo (StringMap& values, const int totalSize) const
387 {
388 setValue (values, "Manufacturer", manufacturer);
389 setValue (values, "Product", product);
390 setValue (values, "SamplePeriod", samplePeriod);
391 setValue (values, "MidiUnityNote", midiUnityNote);
392 setValue (values, "MidiPitchFraction", midiPitchFraction);
393 setValue (values, "SmpteFormat", smpteFormat);
394 setValue (values, "SmpteOffset", smpteOffset);
395 setValue (values, "NumSampleLoops", numSampleLoops);
396 setValue (values, "SamplerData", samplerData);
397
398 for (int i = 0; i < (int) numSampleLoops; ++i)
399 {
400 if ((uint8*) (loops + (i + 1)) > ((uint8*) this) + totalSize)
401 break;
402
403 setValue (values, i, "Identifier", loops[i].identifier);
404 setValue (values, i, "Type", loops[i].type);
405 setValue (values, i, "Start", loops[i].start);
406 setValue (values, i, "End", loops[i].end);
407 setValue (values, i, "Fraction", loops[i].fraction);
408 setValue (values, i, "PlayCount", loops[i].playCount);
409 }
410 }
411
412 template <typename NameType>
413 static uint32 getValue (const StringMap& values, NameType name, const char* def)
414 {
415 return ByteOrder::swapIfBigEndian ((uint32) getValueWithDefault (values, name, def).getIntValue());
416 }
417
418 static uint32 getValue (const StringMap& values, int prefix, const char* name, const char* def)
419 {
420 return getValue (values, "Loop" + String (prefix) + name, def);
421 }
422
423 static MemoryBlock createFrom (const StringMap& values)
424 {
426 auto numLoops = jmin (64, getValueWithDefault (values, "NumSampleLoops", "0").getIntValue());
427
428 data.setSize (roundUpSize (sizeof (SMPLChunk) + (size_t) (jmax (0, numLoops - 1)) * sizeof (SampleLoop)), true);
429
430 auto s = static_cast<SMPLChunk*> (data.getData());
431
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");
439 s->numSampleLoops = ByteOrder::swapIfBigEndian ((uint32) numLoops);
440 s->samplerData = getValue (values, "SamplerData", "0");
441
442 for (int i = 0; i < numLoops; ++i)
443 {
444 auto& loop = s->loops[i];
445 loop.identifier = getValue (values, i, "Identifier", "0");
446 loop.type = getValue (values, i, "Type", "0");
447 loop.start = getValue (values, i, "Start", "0");
448 loop.end = getValue (values, i, "End", "0");
449 loop.fraction = getValue (values, i, "Fraction", "0");
450 loop.playCount = getValue (values, i, "PlayCount", "0");
451 }
452
453 return data;
454 }
455 } JUCE_PACKED;
456
457 //==============================================================================
459 {
467
468 static void setValue (StringMap& values, const char* name, int val)
469 {
470 values[name] = String (val);
471 }
472
473 void copyTo (StringMap& values) const
474 {
475 setValue (values, "MidiUnityNote", baseNote);
476 setValue (values, "Detune", detune);
477 setValue (values, "Gain", gain);
478 setValue (values, "LowNote", lowNote);
479 setValue (values, "HighNote", highNote);
480 setValue (values, "LowVelocity", lowVelocity);
481 setValue (values, "HighVelocity", highVelocity);
482 }
483
484 static int8 getValue (const StringMap& values, const char* name, const char* def)
485 {
486 return (int8) getValueWithDefault (values, name, def).getIntValue();
487 }
488
489 static MemoryBlock createFrom (const StringMap& values)
490 {
492
493 if ( values.find ("LowNote") != values.cend()
494 && values.find ("HighNote") != values.cend())
495 {
496 data.setSize (8, true);
497 auto* inst = static_cast<InstChunk*> (data.getData());
498
499 inst->baseNote = getValue (values, "MidiUnityNote", "60");
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");
506 }
507
508 return data;
509 }
510 } JUCE_PACKED;
511
512 //==============================================================================
513 struct CueChunk
514 {
524
527
528 static void setValue (StringMap& values, int prefix, const char* name, uint32 val)
529 {
530 values["Cue" + String (prefix) + name] = String (ByteOrder::swapIfBigEndian (val));
531 }
532
533 void copyTo (StringMap& values, const int totalSize) const
534 {
535 values["NumCuePoints"] = String (ByteOrder::swapIfBigEndian (numCues));
536
537 for (int i = 0; i < (int) numCues; ++i)
538 {
539 if ((uint8*) (cues + (i + 1)) > ((uint8*) this) + totalSize)
540 break;
541
542 setValue (values, i, "Identifier", cues[i].identifier);
543 setValue (values, i, "Order", cues[i].order);
544 setValue (values, i, "ChunkID", cues[i].chunkID);
545 setValue (values, i, "ChunkStart", cues[i].chunkStart);
546 setValue (values, i, "BlockStart", cues[i].blockStart);
547 setValue (values, i, "Offset", cues[i].offset);
548 }
549 }
550
551 static MemoryBlock createFrom (const StringMap& values)
552 {
554 const int numCues = getValueWithDefault (values, "NumCuePoints", "0").getIntValue();
555
556 if (numCues > 0)
557 {
558 data.setSize (roundUpSize (sizeof (CueChunk) + (size_t) (numCues - 1) * sizeof (Cue)), true);
559
560 auto c = static_cast<CueChunk*> (data.getData());
561
563
564 const String dataChunkID (chunkName ("data"));
565 int nextOrder = 0;
566
567 #if JUCE_DEBUG
568 Array<uint32> identifiers;
569 #endif
570
571 for (int i = 0; i < numCues; ++i)
572 {
573 auto prefix = "Cue" + String (i);
574 auto identifier = (uint32) getValueWithDefault (values, prefix + "Identifier", "0").getIntValue();
575
576 #if JUCE_DEBUG
577 jassert (! identifiers.contains (identifier));
578 identifiers.add (identifier);
579 #endif
580
581 auto order = getValueWithDefault (values, prefix + "Order", String (nextOrder)).getIntValue();
582 nextOrder = jmax (nextOrder, order) + 1;
583
584 auto& cue = c->cues[i];
585 cue.identifier = ByteOrder::swapIfBigEndian ((uint32) identifier);
586 cue.order = ByteOrder::swapIfBigEndian ((uint32) order);
587 cue.chunkID = ByteOrder::swapIfBigEndian ((uint32) getValueWithDefault (values, prefix + "ChunkID", dataChunkID).getIntValue());
588 cue.chunkStart = ByteOrder::swapIfBigEndian ((uint32) getValueWithDefault (values, prefix + "ChunkStart", "0").getIntValue());
589 cue.blockStart = ByteOrder::swapIfBigEndian ((uint32) getValueWithDefault (values, prefix + "BlockStart", "0").getIntValue());
590 cue.offset = ByteOrder::swapIfBigEndian ((uint32) getValueWithDefault (values, prefix + "Offset", "0").getIntValue());
591 }
592 }
593
594 return data;
595 }
596
597 } JUCE_PACKED;
598
599 //==============================================================================
600 namespace ListChunk
601 {
602 static int getValue (const StringMap& values, const String& name)
603 {
604 return getValueWithDefault (values, name, "0").getIntValue();
605 }
606
607 static int getValue (const StringMap& values, const String& prefix, const char* name)
608 {
609 return getValue (values, prefix + name);
610 }
611
612 static void appendLabelOrNoteChunk (const StringMap& values, const String& prefix,
613 const int chunkType, MemoryOutputStream& out)
614 {
615 auto label = getValueWithDefault (values, prefix + "Text", prefix);
616 auto labelLength = (int) label.getNumBytesAsUTF8() + 1;
617 auto chunkLength = 4 + labelLength + (labelLength & 1);
618
619 out.writeInt (chunkType);
620 out.writeInt (chunkLength);
621 out.writeInt (getValue (values, prefix, "Identifier"));
622 out.write (label.toUTF8(), (size_t) labelLength);
623
624 if ((out.getDataSize() & 1) != 0)
625 out.writeByte (0);
626 }
627
628 static void appendExtraChunk (const StringMap& values, const String& prefix, MemoryOutputStream& out)
629 {
630 auto text = getValueWithDefault (values, prefix + "Text", prefix);
631
632 auto textLength = (int) text.getNumBytesAsUTF8() + 1; // include null terminator
633 auto chunkLength = textLength + 20 + (textLength & 1);
634
635 out.writeInt (chunkName ("ltxt"));
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);
645
646 if ((out.getDataSize() & 1) != 0)
647 out.writeByte (0);
648 }
649
650 static MemoryBlock createFrom (const StringMap& values)
651 {
652 auto numCueLabels = getValue (values, "NumCueLabels");
653 auto numCueNotes = getValue (values, "NumCueNotes");
654 auto numCueRegions = getValue (values, "NumCueRegions");
655
657
658 if (numCueLabels + numCueNotes + numCueRegions > 0)
659 {
660 out.writeInt (chunkName ("adtl"));
661
662 for (int i = 0; i < numCueLabels; ++i)
663 appendLabelOrNoteChunk (values, "CueLabel" + String (i), chunkName ("labl"), out);
664
665 for (int i = 0; i < numCueNotes; ++i)
666 appendLabelOrNoteChunk (values, "CueNote" + String (i), chunkName ("note"), out);
667
668 for (int i = 0; i < numCueRegions; ++i)
669 appendExtraChunk (values, "CueRegion" + String (i), out);
670 }
671
672 return out.getMemoryBlock();
673 }
674 }
675
676 //==============================================================================
679 {
680 static const char* const types[] =
681 {
763 };
764
765 static bool isMatchingTypeIgnoringCase (const int value, const char* const name) noexcept
766 {
767 for (int i = 0; i < 4; ++i)
768 if ((juce_wchar) name[i] != CharacterFunctions::toUpperCase ((juce_wchar) ((value >> (i * 8)) & 0xff)))
769 return false;
770
771 return true;
772 }
773
774 static void addToMetadata (StringMap& values, InputStream& input, int64 chunkEnd)
775 {
776 while (input.getPosition() < chunkEnd)
777 {
778 auto infoType = input.readInt();
779 auto infoLength = chunkEnd - input.getPosition();
780
781 if (infoLength > 0)
782 {
783 infoLength = jmin (infoLength, (int64) input.readInt());
784
785 if (infoLength <= 0)
786 return;
787
788 for (auto& type : types)
789 {
790 if (isMatchingTypeIgnoringCase (infoType, type))
791 {
792 MemoryBlock mb;
793 input.readIntoMemoryBlock (mb, (ssize_t) infoLength);
794 values[type] = String::createStringFromData ((const char*) mb.getData(),
795 (int) mb.getSize());
796 break;
797 }
798 }
799 }
800 }
801 }
802
803 static bool writeValue (const StringMap& values, MemoryOutputStream& out, const char* paramName)
804 {
805 auto value = getValueWithDefault (values, paramName, {});
806
807 if (value.isEmpty())
808 return false;
809
810 auto valueLength = (int) value.getNumBytesAsUTF8() + 1;
811 auto chunkLength = valueLength + (valueLength & 1);
812
813 out.writeInt (chunkName (paramName));
814 out.writeInt (chunkLength);
815 out.write (value.toUTF8(), (size_t) valueLength);
816
817 if ((out.getDataSize() & 1) != 0)
818 out.writeByte (0);
819
820 return true;
821 }
822
823 static MemoryBlock createFrom (const StringMap& values)
824 {
826 out.writeInt (chunkName ("INFO"));
827 bool anyParamsDefined = false;
828
829 for (auto& type : types)
830 if (writeValue (values, out, type))
831 anyParamsDefined = true;
832
833 return anyParamsDefined ? out.getMemoryBlock() : MemoryBlock();
834 }
835 }
836
837 //==============================================================================
839 {
841 AcidChunk (InputStream& input, size_t length)
842 {
843 zerostruct (*this);
844 input.read (this, (int) jmin (sizeof (*this), length));
845 }
846
847 AcidChunk (const StringMap& values)
848 {
849 zerostruct (*this);
850
856
857 if (getValueWithDefault (values, WavAudioFormat::acidRootSet).getIntValue() != 0)
859
863
864 const auto iter = values.find (WavAudioFormat::acidTempo);
865
866 if (iter != values.cend())
867 tempo = swapFloatByteOrder (iter->second.getFloatValue());
868 }
869
870 static MemoryBlock createFrom (const StringMap& values)
871 {
872 return AcidChunk (values).toMemoryBlock();
873 }
874
876 {
877 return (flags != 0 || rootNote != 0 || numBeats != 0 || meterDenominator != 0 || meterNumerator != 0)
878 ? MemoryBlock (this, sizeof (*this)) : MemoryBlock();
879 }
880
897
898 void setBoolFlag (StringMap& values, const char* name, uint32 mask) const
899 {
900 values[name] = (flags & ByteOrder::swapIfBigEndian (mask)) ? "1" : "0";
901 }
902
903 static uint32 getFlagIfPresent (const StringMap& values, const char* name, uint32 flag)
904 {
905 return getValueWithDefault (values, name).getIntValue() != 0 ? ByteOrder::swapIfBigEndian (flag) : 0;
906 }
907
908 static float swapFloatByteOrder (const float x) noexcept
909 {
910 #ifdef JUCE_BIG_ENDIAN
911 union { uint32 asInt; float asFloat; } n;
912 n.asFloat = x;
913 n.asInt = ByteOrder::swap (n.asInt);
914 return n.asFloat;
915 #else
916 return x;
917 #endif
918 }
919
927 float tempo;
928
929 } JUCE_PACKED;
930
931 //==============================================================================
933 {
934 static MemoryBlock createFrom (const StringMap& values)
935 {
938
939 if (s.isNotEmpty())
940 {
941 out.writeString (s);
942
943 if ((out.getDataSize() & 1) != 0)
944 out.writeByte (0);
945 }
946
947 return out.getMemoryBlock();
948 }
949 };
950
951 //=============================================================================
952 namespace IXMLChunk
953 {
954 static const std::unordered_set<String> aswgMetadataKeys
955 {
1039 };
1040
1041 static void addToMetadata (StringMap& destValues, const String& source)
1042 {
1043 if (auto xml = parseXML (source))
1044 {
1045 if (xml->hasTagName ("BWFXML"))
1046 {
1047 if (const auto* entry = xml->getChildByName (WavAudioFormat::aswgVersion))
1048 destValues[WavAudioFormat::aswgVersion] = entry->getAllSubText();
1049
1050 if (const auto* aswgElement = xml->getChildByName ("ASWG"))
1051 {
1052 for (const auto* entry : aswgElement->getChildIterator())
1053 {
1054 const auto& tag = entry->getTagName();
1055
1056 if (aswgMetadataKeys.find (tag) != aswgMetadataKeys.end())
1057 destValues[tag] = entry->getAllSubText();
1058 }
1059 }
1060 }
1061 }
1062 }
1063
1064 static MemoryBlock createFrom (const StringMap& values)
1065 {
1066 auto createTextElement = [] (const StringRef& key, const StringRef& value)
1067 {
1068 auto* elem = new XmlElement (key);
1069 elem->addTextElement (value);
1070 return elem;
1071 };
1072
1073 std::unique_ptr<XmlElement> aswgElement;
1074
1075 for (const auto& pair : values)
1076 {
1077 if (aswgMetadataKeys.find (pair.first) != aswgMetadataKeys.end())
1078 {
1079 if (aswgElement == nullptr)
1080 aswgElement = std::make_unique<XmlElement> ("ASWG");
1081
1082 aswgElement->addChildElement (createTextElement (pair.first, pair.second));
1083 }
1084 }
1085
1086 MemoryOutputStream outputStream;
1087
1088 if (aswgElement != nullptr)
1089 {
1090 XmlElement xml ("BWFXML");
1091 auto aswgVersion = getValueWithDefault (values, WavAudioFormat::aswgVersion, "3.01");
1092 xml.addChildElement (createTextElement (WavAudioFormat::aswgVersion, aswgVersion));
1093 xml.addChildElement (aswgElement.release());
1094 xml.writeTo (outputStream);
1095 outputStream.writeRepeatedByte (0, outputStream.getDataSize());
1096 }
1097
1098 return outputStream.getMemoryBlock();
1099 }
1100 }
1101
1102 //==============================================================================
1103 namespace AXMLChunk
1104 {
1105 static void addToMetadata (StringMap& destValues, const String& source)
1106 {
1107 if (auto xml = parseXML (source))
1108 {
1109 if (xml->hasTagName ("ebucore:ebuCoreMain"))
1110 {
1111 if (auto xml2 = xml->getChildByName ("ebucore:coreMetadata"))
1112 {
1113 if (auto xml3 = xml2->getChildByName ("ebucore:identifier"))
1114 {
1115 if (auto xml4 = xml3->getChildByName ("dc:identifier"))
1116 {
1117 auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true);
1118
1119 if (ISRCCode.isNotEmpty())
1120 {
1121 // We set ISRC here for backwards compatibility.
1122 // If the INFO 'source' field is set in the info chunk, then the
1123 // value for this key will be overwritten later.
1125 }
1126 }
1127 }
1128 }
1129 }
1130 }
1131 }
1132
1133 static MemoryBlock createFrom (const StringMap& values)
1134 {
1135 // Use the new ISRC key if it is present, but fall back to the
1136 // INFO 'source' value for backwards compatibility.
1137 auto ISRC = getValueWithDefault (values,
1140
1142
1143 if (ISRC.isNotEmpty())
1144 {
1145 // If you are trying to set the ISRC, make sure that you are using
1146 // WavAudioFormat::internationalStandardRecordingCode as the metadata key,
1147 // and that the value is 12 characters long. If you are trying to set the
1148 // 'source' field in the INFO chunk, set the
1149 // WavAudioFormat::internationalStandardRecordingCode metadata field to the
1150 // empty string to silence this assertion.
1151 jassert (ISRC.length() == 12);
1152
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>";
1165
1166 xml.writeRepeatedByte (0, xml.getDataSize()); // ensures even size, null termination and room for future growing
1167 }
1168
1169 return xml.getMemoryBlock();
1170 }
1171 }
1172
1173 //==============================================================================
1175 {
1180
1181 bool operator== (const ExtensibleWavSubFormat& other) const noexcept { return memcmp (this, &other, sizeof (*this)) == 0; }
1182 bool operator!= (const ExtensibleWavSubFormat& other) const noexcept { return ! operator== (other); }
1183
1184 } JUCE_PACKED;
1185
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 } };
1189
1190 struct DataSize64Chunk // chunk ID = 'ds64' if data size > 0xffffffff, 'JUNK' otherwise
1191 {
1192 uint32 riffSizeLow; // low 4 byte size of RF64 block
1193 uint32 riffSizeHigh; // high 4 byte size of RF64 block
1194 uint32 dataSizeLow; // low 4 byte size of data chunk
1195 uint32 dataSizeHigh; // high 4 byte size of data chunk
1196 uint32 sampleCountLow; // low 4 byte sample count of fact chunk
1197 uint32 sampleCountHigh; // high 4 byte sample count of fact chunk
1198 uint32 tableLength; // number of valid entries in array 'table'
1199 } JUCE_PACKED;
1200
1201 #if JUCE_MSVC
1202 #pragma pack (pop)
1203 #endif
1204}
1205
1206//==============================================================================
1208{
1209public:
1211 {
1212 using namespace WavFileHelpers;
1213 uint64 len = 0, end = 0;
1214 int cueNoteIndex = 0;
1215 int cueLabelIndex = 0;
1216 int cueRegionIndex = 0;
1217
1218 StringMap dict;
1219
1220 auto streamStartPos = input->getPosition();
1221 auto firstChunkType = input->readInt();
1222
1223 if (firstChunkType == chunkName ("RF64"))
1224 {
1225 input->skipNextBytes (4); // size is -1 for RF64
1226 isRF64 = true;
1227 }
1228 else if (firstChunkType == chunkName ("RIFF"))
1229 {
1230 len = (uint64) (uint32) input->readInt();
1231 end = len + (uint64) input->getPosition();
1232 }
1233 else
1234 {
1235 return;
1236 }
1237
1238 auto startOfRIFFChunk = input->getPosition();
1239
1240 if (input->readInt() == chunkName ("WAVE"))
1241 {
1242 if (isRF64 && input->readInt() == chunkName ("ds64"))
1243 {
1244 auto length = (uint32) input->readInt();
1245
1246 if (length < 28)
1247 return;
1248
1249 auto chunkEnd = input->getPosition() + length + (length & 1);
1250 len = (uint64) input->readInt64();
1251 end = len + (uint64) startOfRIFFChunk;
1252 dataLength = input->readInt64();
1253 input->setPosition (chunkEnd);
1254 }
1255
1256 while ((uint64) input->getPosition() < end && ! input->isExhausted())
1257 {
1258 auto chunkType = input->readInt();
1259 auto length = (uint32) input->readInt();
1260 auto chunkEnd = input->getPosition() + length + (length & 1);
1261
1262 if (chunkType == chunkName ("fmt "))
1263 {
1264 // read the format chunk
1265 auto format = (unsigned short) input->readShort();
1266 numChannels = (unsigned int) input->readShort();
1267 sampleRate = input->readInt();
1268 auto bytesPerSec = input->readInt();
1269 input->skipNextBytes (2);
1270 bitsPerSample = (unsigned int) (int) input->readShort();
1271
1272 if (bitsPerSample > 64 && (int) sampleRate != 0)
1273 {
1274 bytesPerFrame = bytesPerSec / (int) sampleRate;
1275
1276 if (numChannels != 0)
1277 bitsPerSample = 8 * (unsigned int) bytesPerFrame / numChannels;
1278 }
1279 else
1280 {
1282 }
1283
1284 if (format == 3)
1285 {
1286 usesFloatingPointData = true;
1287 }
1288 else if (format == 0xfffe) // WAVE_FORMAT_EXTENSIBLE
1289 {
1290 if (length < 40) // too short
1291 {
1292 bytesPerFrame = 0;
1293 }
1294 else
1295 {
1296 input->skipNextBytes (4); // skip over size and bitsPerSample
1297 auto channelMask = input->readInt();
1298 dict["ChannelMask"] = String (channelMask);
1300
1301 ExtensibleWavSubFormat subFormat;
1302 subFormat.data1 = (uint32) input->readInt();
1303 subFormat.data2 = (uint16) input->readShort();
1304 subFormat.data3 = (uint16) input->readShort();
1305 input->read (subFormat.data4, sizeof (subFormat.data4));
1306
1307 if (subFormat == IEEEFloatFormat)
1308 usesFloatingPointData = true;
1309 else if (subFormat != pcmFormat && subFormat != ambisonicFormat)
1310 bytesPerFrame = 0;
1311 }
1312 }
1313 else if (format == 0x674f // WAVE_FORMAT_OGG_VORBIS_MODE_1
1314 || format == 0x6750 // WAVE_FORMAT_OGG_VORBIS_MODE_2
1315 || format == 0x6751 // WAVE_FORMAT_OGG_VORBIS_MODE_3
1316 || format == 0x676f // WAVE_FORMAT_OGG_VORBIS_MODE_1_PLUS
1317 || format == 0x6770 // WAVE_FORMAT_OGG_VORBIS_MODE_2_PLUS
1318 || format == 0x6771) // WAVE_FORMAT_OGG_VORBIS_MODE_3_PLUS
1319 {
1320 isSubformatOggVorbis = true;
1321 sampleRate = 0; // to mark the wav reader as failed
1322 input->setPosition (streamStartPos);
1323 return;
1324 }
1325 else if (format != 1)
1326 {
1327 bytesPerFrame = 0;
1328 }
1329 }
1330 else if (chunkType == chunkName ("data"))
1331 {
1332 if (isRF64)
1333 {
1334 if (dataLength > 0)
1335 chunkEnd = input->getPosition() + dataLength + (dataLength & 1);
1336 }
1337 else
1338 {
1340 }
1341
1342 dataChunkStart = input->getPosition();
1344 }
1345 else if (chunkType == chunkName ("bext"))
1346 {
1347 bwavChunkStart = input->getPosition();
1348 bwavSize = length;
1349
1351 bwav.calloc (jmax ((size_t) length + 1, sizeof (BWAVChunk)), 1);
1352 input->read (bwav, (int) length);
1353 bwav->copyTo (dict, (int) length);
1354 }
1355 else if (chunkType == chunkName ("smpl"))
1356 {
1358 smpl.calloc (jmax ((size_t) length + 1, sizeof (SMPLChunk)), 1);
1359 input->read (smpl, (int) length);
1360 smpl->copyTo (dict, (int) length);
1361 }
1362 else if (chunkType == chunkName ("inst") || chunkType == chunkName ("INST")) // need to check which...
1363 {
1365 inst.calloc (jmax ((size_t) length + 1, sizeof (InstChunk)), 1);
1366 input->read (inst, (int) length);
1367 inst->copyTo (dict);
1368 }
1369 else if (chunkType == chunkName ("cue "))
1370 {
1372 cue.calloc (jmax ((size_t) length + 1, sizeof (CueChunk)), 1);
1373 input->read (cue, (int) length);
1374 cue->copyTo (dict, (int) length);
1375 }
1376 else if (chunkType == chunkName ("axml"))
1377 {
1378 MemoryBlock axml;
1379 input->readIntoMemoryBlock (axml, (ssize_t) length);
1380 AXMLChunk::addToMetadata (dict, axml.toString());
1381 }
1382 else if (chunkType == chunkName ("iXML"))
1383 {
1384 MemoryBlock ixml;
1385 input->readIntoMemoryBlock (ixml, (ssize_t) length);
1386 IXMLChunk::addToMetadata (dict, ixml.toString());
1387 }
1388 else if (chunkType == chunkName ("LIST"))
1389 {
1390 auto subChunkType = input->readInt();
1391
1392 if (subChunkType == chunkName ("info") || subChunkType == chunkName ("INFO"))
1393 {
1394 ListInfoChunk::addToMetadata (dict, *input, chunkEnd);
1395 }
1396 else if (subChunkType == chunkName ("adtl"))
1397 {
1398 while (input->getPosition() < chunkEnd)
1399 {
1400 auto adtlChunkType = input->readInt();
1401 auto adtlLength = (uint32) input->readInt();
1402 auto adtlChunkEnd = input->getPosition() + (adtlLength + (adtlLength & 1));
1403
1404 if (adtlChunkType == chunkName ("labl") || adtlChunkType == chunkName ("note"))
1405 {
1406 String prefix;
1407
1408 if (adtlChunkType == chunkName ("labl"))
1409 prefix << "CueLabel" << cueLabelIndex++;
1410 else if (adtlChunkType == chunkName ("note"))
1411 prefix << "CueNote" << cueNoteIndex++;
1412
1413 auto identifier = (uint32) input->readInt();
1414 auto stringLength = (int) adtlLength - 4;
1415
1416 MemoryBlock textBlock;
1417 input->readIntoMemoryBlock (textBlock, stringLength);
1418
1419 dict[prefix + "Identifier"] = String (identifier);
1420 dict[prefix + "Text"] = textBlock.toString();
1421 }
1422 else if (adtlChunkType == chunkName ("ltxt"))
1423 {
1424 auto prefix = "CueRegion" + String (cueRegionIndex++);
1425 auto identifier = (uint32) input->readInt();
1426 auto sampleLength = (uint32) input->readInt();
1427 auto purpose = (uint32) input->readInt();
1428 auto country = (uint16) input->readShort();
1429 auto language = (uint16) input->readShort();
1430 auto dialect = (uint16) input->readShort();
1431 auto codePage = (uint16) input->readShort();
1432 auto stringLength = adtlLength - 20;
1433
1434 MemoryBlock textBlock;
1435 input->readIntoMemoryBlock (textBlock, (int) stringLength);
1436
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();
1445 }
1446
1447 input->setPosition (adtlChunkEnd);
1448 }
1449 }
1450 }
1451 else if (chunkType == chunkName ("acid"))
1452 {
1453 AcidChunk (*input, length).addToMetadata (dict);
1454 }
1455 else if (chunkType == chunkName ("Trkn"))
1456 {
1457 MemoryBlock tracktion;
1458 input->readIntoMemoryBlock (tracktion, (ssize_t) length);
1459 dict[WavAudioFormat::tracktionLoopInfo] = tracktion.toString();
1460 }
1461 else if (chunkEnd <= input->getPosition())
1462 {
1463 break;
1464 }
1465
1466 input->setPosition (chunkEnd);
1467 }
1468 }
1469
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";
1474
1475 metadataValues.addUnorderedMap (dict);
1476 }
1477
1478 //==============================================================================
1479 bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
1480 int64 startSampleInFile, int numSamples) override
1481 {
1482 clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
1483 startSampleInFile, numSamples, lengthInSamples);
1484
1485 if (numSamples <= 0)
1486 return true;
1487
1488 input->setPosition (dataChunkStart + startSampleInFile * bytesPerFrame);
1489
1490 while (numSamples > 0)
1491 {
1492 const int tempBufSize = 480 * 3 * 4; // (keep this a multiple of 3)
1493 char tempBuffer[tempBufSize];
1494
1495 auto numThisTime = jmin (tempBufSize / bytesPerFrame, numSamples);
1496 auto bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame);
1497
1498 if (bytesRead < numThisTime * bytesPerFrame)
1499 {
1500 jassert (bytesRead >= 0);
1501 zeromem (tempBuffer + bytesRead, (size_t) (numThisTime * bytesPerFrame - bytesRead));
1502 }
1503
1505 destSamples, startOffsetInDestBuffer, numDestChannels,
1506 tempBuffer, (int) numChannels, numThisTime);
1507
1508 startOffsetInDestBuffer += numThisTime;
1509 numSamples -= numThisTime;
1510 }
1511
1512 return true;
1513 }
1514
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
1518 {
1519 switch (numBitsPerSample)
1520 {
1521 case 8: ReadHelper<AudioData::Int32, AudioData::UInt8, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numberOfChannels, numSamples); break;
1522 case 16: ReadHelper<AudioData::Int32, AudioData::Int16, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numberOfChannels, numSamples); break;
1523 case 24: ReadHelper<AudioData::Int32, AudioData::Int24, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numberOfChannels, numSamples); break;
1524 case 32: if (floatingPointData) ReadHelper<AudioData::Float32, AudioData::Float32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numberOfChannels, numSamples);
1525 else ReadHelper<AudioData::Int32, AudioData::Int32, AudioData::LittleEndian>::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numberOfChannels, numSamples);
1526 break;
1527 default: jassertfalse; break;
1528 }
1529 }
1530
1531 //==============================================================================
1533 {
1534 if (channelLayout.size() == static_cast<int> (numChannels))
1535 return channelLayout;
1536
1537 return WavFileHelpers::canonicalWavChannelSet (static_cast<int> (numChannels));
1538 }
1539
1540 static AudioChannelSet getChannelLayoutFromMask (int dwChannelMask, size_t totalNumChannels)
1541 {
1542 AudioChannelSet wavFileChannelLayout;
1543
1544 // AudioChannelSet and wav's dwChannelMask are compatible
1545 BigInteger channelBits (dwChannelMask);
1546
1547 for (auto bit = channelBits.findNextSetBit (0); bit >= 0; bit = channelBits.findNextSetBit (bit + 1))
1548 wavFileChannelLayout.addChannel (static_cast<AudioChannelSet::ChannelType> (bit + 1));
1549
1550 // channel layout and number of channels do not match
1551 if (wavFileChannelLayout.size() != static_cast<int> (totalNumChannels))
1552 {
1553 // for backward compatibility with old wav files, assume 1 or 2
1554 // channel wav files are mono/stereo respectively
1555 if (totalNumChannels <= 2 && dwChannelMask == 0)
1556 wavFileChannelLayout = AudioChannelSet::canonicalChannelSet (static_cast<int> (totalNumChannels));
1557 else
1558 {
1559 auto discreteSpeaker = static_cast<int> (AudioChannelSet::discreteChannel0);
1560
1561 while (wavFileChannelLayout.size() < static_cast<int> (totalNumChannels))
1562 wavFileChannelLayout.addChannel (static_cast<AudioChannelSet::ChannelType> (discreteSpeaker++));
1563 }
1564 }
1565
1566 return wavFileChannelLayout;
1567 }
1568
1572 bool isRF64 = false;
1574
1576
1577private:
1579};
1580
1581//==============================================================================
1583{
1584public:
1585 WavAudioFormatWriter (OutputStream* const out, const double rate,
1586 const AudioChannelSet& channelLayoutToUse, const unsigned int bits,
1587 const StringPairArray& metadataValues)
1588 : AudioFormatWriter (out, wavFormatName, rate, channelLayoutToUse, bits)
1589 {
1590 using namespace WavFileHelpers;
1591
1592 if (metadataValues.size() > 0)
1593 {
1594 // The meta data should have been sanitised for the WAV format.
1595 // If it was originally sourced from an AIFF file the MetaDataSource
1596 // key should be removed (or set to "WAV") once this has been done
1597 jassert (metadataValues.getValue ("MetaDataSource", "None") != "AIFF");
1598
1599 const auto map = toMap (metadataValues);
1600
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);
1611 }
1612
1613 headerPosition = out->getPosition();
1614 writeHeader();
1615 }
1616
1618 {
1619 writeHeader();
1620 }
1621
1622 //==============================================================================
1623 bool write (const int** data, int numSamples) override
1624 {
1625 jassert (numSamples >= 0);
1626 jassert (data != nullptr && *data != nullptr); // the input must contain at least one channel!
1627
1628 if (writeFailed)
1629 return false;
1630
1631 auto bytes = numChannels * (size_t) numSamples * bitsPerSample / 8;
1632 tempBlock.ensureSize (bytes, false);
1633
1634 switch (bitsPerSample)
1635 {
1640 default: jassertfalse; break;
1641 }
1642
1643 if (! output->write (tempBlock.getData(), bytes))
1644 {
1645 // failed to write to disk, so let's try writing the header.
1646 // If it's just run out of disk space, then if it does manage
1647 // to write the header, we'll still have a usable file..
1648 writeHeader();
1649 writeFailed = true;
1650 return false;
1651 }
1652
1653 bytesWritten += bytes;
1654 lengthInSamples += (uint64) numSamples;
1655 return true;
1656 }
1657
1658 bool flush() override
1659 {
1660 auto lastWritePos = output->getPosition();
1661 writeHeader();
1662
1663 if (output->setPosition (lastWritePos))
1664 return true;
1665
1666 // if this fails, you've given it an output stream that can't seek! It needs
1667 // to be able to seek back to write the header
1669 return false;
1670 }
1671
1672private:
1676 bool writeFailed = false;
1677
1679 {
1680 if ((bytesWritten & 1) != 0) // pad to an even length
1681 output->writeByte (0);
1682
1683 using namespace WavFileHelpers;
1684
1685 if (headerPosition != output->getPosition() && ! output->setPosition (headerPosition))
1686 {
1687 // if this fails, you've given it an output stream that can't seek! It needs to be
1688 // able to seek back to go back and write the header after the data has been written.
1690 return;
1691 }
1692
1693 const size_t bytesPerFrame = numChannels * bitsPerSample / 8;
1694 uint64 audioDataSize = bytesPerFrame * lengthInSamples;
1696
1697 const bool isRF64 = (bytesWritten >= 0x100000000LL);
1698 const bool isWaveFmtEx = isRF64 || (channelMask != 0);
1699
1700 int64 riffChunkSize = (int64) (4 /* 'RIFF' */ + 8 + 40 /* WAVEFORMATEX */
1701 + 8 + audioDataSize + (audioDataSize & 1)
1712 + (8 + 28)); // (ds64 chunk)
1713
1714 riffChunkSize += (riffChunkSize & 1);
1715
1716 if (isRF64)
1717 writeChunkHeader (chunkName ("RF64"), -1);
1718 else
1719 writeChunkHeader (chunkName ("RIFF"), (int) riffChunkSize);
1720
1721 output->writeInt (chunkName ("WAVE"));
1722
1723 if (! isRF64)
1724 {
1725 #if ! JUCE_WAV_DO_NOT_PAD_HEADER_SIZE
1726 /* NB: This junk chunk is added for padding, so that the header is a fixed size
1727 regardless of whether it's RF64 or not. That way, we can begin recording a file,
1728 and when it's finished, can go back and write either a RIFF or RF64 header,
1729 depending on whether more than 2^32 samples were written.
1730
1731 The JUCE_WAV_DO_NOT_PAD_HEADER_SIZE macro allows you to disable this feature in case
1732 you need to create files for crappy WAV players with bugs that stop them skipping chunks
1733 which they don't recognise. But DO NOT USE THIS option unless you really have no choice,
1734 because it means that if you write more than 2^32 samples to the file, you'll corrupt it.
1735 */
1736 writeChunkHeader (chunkName ("JUNK"), 28 + (isWaveFmtEx? 0 : 24));
1737 output->writeRepeatedByte (0, 28 /* ds64 */ + (isWaveFmtEx? 0 : 24));
1738 #endif
1739 }
1740 else
1741 {
1742 #if JUCE_WAV_DO_NOT_PAD_HEADER_SIZE
1743 // If you disable padding, then you MUST NOT write more than 2^32 samples to a file.
1745 #endif
1746
1747 writeChunkHeader (chunkName ("ds64"), 28); // chunk size for uncompressed data (no table)
1748 output->writeInt64 (riffChunkSize);
1749 output->writeInt64 ((int64) audioDataSize);
1750 output->writeRepeatedByte (0, 12);
1751 }
1752
1753 if (isWaveFmtEx)
1754 {
1755 writeChunkHeader (chunkName ("fmt "), 40);
1756 output->writeShort ((short) (uint16) 0xfffe); // WAVE_FORMAT_EXTENSIBLE
1757 }
1758 else
1759 {
1760 writeChunkHeader (chunkName ("fmt "), 16);
1761 output->writeShort (bitsPerSample < 32 ? (short) 1 /*WAVE_FORMAT_PCM*/
1762 : (short) 3 /*WAVE_FORMAT_IEEE_FLOAT*/);
1763 }
1764
1765 output->writeShort ((short) numChannels);
1766 output->writeInt ((int) sampleRate);
1767 output->writeInt ((int) ((double) bytesPerFrame * sampleRate)); // nAvgBytesPerSec
1768 output->writeShort ((short) bytesPerFrame); // nBlockAlign
1769 output->writeShort ((short) bitsPerSample); // wBitsPerSample
1770
1771 if (isWaveFmtEx)
1772 {
1773 output->writeShort (22); // cbSize (size of the extension)
1774 output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
1775 output->writeInt (channelMask);
1776
1777 const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;
1778
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));
1783 }
1784
1785 writeChunk (bwavChunk, chunkName ("bext"));
1786 writeChunk (ixmlChunk, chunkName ("iXML"));
1787 writeChunk (axmlChunk, chunkName ("axml"));
1788 writeChunk (smplChunk, chunkName ("smpl"));
1789 writeChunk (instChunk, chunkName ("inst"), 7);
1790 writeChunk (cueChunk, chunkName ("cue "));
1791 writeChunk (listChunk, chunkName ("LIST"));
1792 writeChunk (listInfoChunk, chunkName ("LIST"));
1793 writeChunk (acidChunk, chunkName ("acid"));
1794 writeChunk (trckChunk, chunkName ("Trkn"));
1795
1796 writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame));
1797
1799 }
1800
1801 static size_t chunkSize (const MemoryBlock& data) noexcept { return data.isEmpty() ? 0 : (8 + data.getSize()); }
1802
1803 void writeChunkHeader (int chunkType, int size) const
1804 {
1805 output->writeInt (chunkType);
1806 output->writeInt (size);
1807 }
1808
1809 void writeChunk (const MemoryBlock& data, int chunkType, int size = 0) const
1810 {
1811 if (! data.isEmpty())
1812 {
1813 writeChunkHeader (chunkType, size != 0 ? size : (int) data.getSize());
1814 *output << data;
1815 }
1816 }
1817
1819 {
1820 if (layout.isDiscreteLayout())
1821 return 0;
1822
1823 // Don't add an extended format chunk for mono and stereo. Basically, all wav players
1824 // interpret a wav file with only one or two channels to be mono or stereo anyway.
1825 if (layout == AudioChannelSet::mono() || layout == AudioChannelSet::stereo())
1826 return 0;
1827
1828 auto channels = layout.getChannelTypes();
1829 auto wavChannelMask = 0;
1830
1831 for (auto channel : channels)
1832 {
1833 int wavChannelBit = static_cast<int> (channel) - 1;
1834 jassert (wavChannelBit >= 0 && wavChannelBit <= 31);
1835
1836 wavChannelMask |= (1 << wavChannelBit);
1837 }
1838
1839 return wavChannelMask;
1840 }
1841
1843};
1844
1845//==============================================================================
1847{
1848public:
1849 MemoryMappedWavReader (const File& wavFile, const WavAudioFormatReader& reader)
1850 : MemoryMappedAudioFormatReader (wavFile, reader, reader.dataChunkStart,
1851 reader.dataLength, reader.bytesPerFrame)
1852 {
1853 }
1854
1855 bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
1856 int64 startSampleInFile, int numSamples) override
1857 {
1858 clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
1859 startSampleInFile, numSamples, lengthInSamples);
1860
1861 if (map == nullptr || ! mappedSection.contains (Range<int64> (startSampleInFile, startSampleInFile + numSamples)))
1862 {
1863 jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read.
1864 return false;
1865 }
1866
1868 destSamples, startOffsetInDestBuffer, numDestChannels,
1869 sampleToPointer (startSampleInFile), (int) numChannels, numSamples);
1870 return true;
1871 }
1872
1873 void getSample (int64 sample, float* result) const noexcept override
1874 {
1875 auto num = (int) numChannels;
1876
1877 if (map == nullptr || ! mappedSection.contains (sample))
1878 {
1879 jassertfalse; // you must make sure that the window contains all the samples you're going to attempt to read.
1880
1881 zeromem (result, (size_t) num * sizeof (float));
1882 return;
1883 }
1884
1885 auto dest = &result;
1886 auto source = sampleToPointer (sample);
1887
1888 switch (bitsPerSample)
1889 {
1895 break;
1896 default: jassertfalse; break;
1897 }
1898 }
1899
1900 void readMaxLevels (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead) override
1901 {
1902 numSamples = jmin (numSamples, lengthInSamples - startSampleInFile);
1903
1904 if (map == nullptr || numSamples <= 0 || ! mappedSection.contains (Range<int64> (startSampleInFile, startSampleInFile + numSamples)))
1905 {
1906 jassert (numSamples <= 0); // you must make sure that the window contains all the samples you're going to attempt to read.
1907
1908 for (int i = 0; i < numChannelsToRead; ++i)
1909 results[i] = {};
1910
1911 return;
1912 }
1913
1914 switch (bitsPerSample)
1915 {
1916 case 8: scanMinAndMax<AudioData::UInt8> (startSampleInFile, numSamples, results, numChannelsToRead); break;
1917 case 16: scanMinAndMax<AudioData::Int16> (startSampleInFile, numSamples, results, numChannelsToRead); break;
1918 case 24: scanMinAndMax<AudioData::Int24> (startSampleInFile, numSamples, results, numChannelsToRead); break;
1919 case 32: if (usesFloatingPointData) scanMinAndMax<AudioData::Float32> (startSampleInFile, numSamples, results, numChannelsToRead);
1920 else scanMinAndMax<AudioData::Int32> (startSampleInFile, numSamples, results, numChannelsToRead);
1921 break;
1922 default: jassertfalse; break;
1923 }
1924 }
1925
1927
1928private:
1929 template <typename SampleType>
1930 void scanMinAndMax (int64 startSampleInFile, int64 numSamples, Range<float>* results, int numChannelsToRead) const noexcept
1931 {
1932 for (int i = 0; i < numChannelsToRead; ++i)
1933 results[i] = scanMinAndMaxInterleaved<SampleType, AudioData::LittleEndian> (i, startSampleInFile, numSamples);
1934 }
1935
1937};
1938
1939//==============================================================================
1942
1944{
1945 return { 8000, 11025, 12000, 16000, 22050, 32000, 44100,
1946 48000, 88200, 96000, 176400, 192000, 352800, 384000 };
1947}
1948
1950{
1951 return { 8, 16, 24, 32 };
1952}
1953
1954bool WavAudioFormat::canDoStereo() { return true; }
1955bool WavAudioFormat::canDoMono() { return true; }
1956
1958{
1959 auto channelTypes = channelSet.getChannelTypes();
1960
1961 // When
1962 if (channelSet.isDiscreteLayout())
1963 return true;
1964
1965 // WAV supports all channel types from left ... topRearRight
1966 for (auto channel : channelTypes)
1967 if (channel < AudioChannelSet::left || channel > AudioChannelSet::topRearRight)
1968 return false;
1969
1970 return true;
1971}
1972
1973AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream, bool deleteStreamIfOpeningFails)
1974{
1975 std::unique_ptr<WavAudioFormatReader> r (new WavAudioFormatReader (sourceStream));
1976
1977 #if JUCE_USE_OGGVORBIS
1978 if (r->isSubformatOggVorbis)
1979 {
1980 r->input = nullptr;
1981 return OggVorbisAudioFormat().createReaderFor (sourceStream, deleteStreamIfOpeningFails);
1982 }
1983 #endif
1984
1985 if (r->sampleRate > 0 && r->numChannels > 0 && r->bytesPerFrame > 0 && r->bitsPerSample <= 32)
1986 return r.release();
1987
1988 if (! deleteStreamIfOpeningFails)
1989 r->input = nullptr;
1990
1991 return nullptr;
1992}
1993
1998
2000{
2001 if (fin != nullptr)
2002 {
2003 WavAudioFormatReader reader (fin);
2004
2005 if (reader.lengthInSamples > 0)
2006 return new MemoryMappedWavReader (fin->getFile(), reader);
2007 }
2008
2009 return nullptr;
2010}
2011
2013 unsigned int numChannels, int bitsPerSample,
2014 const StringPairArray& metadataValues, int qualityOptionIndex)
2015{
2016 return createWriterFor (out, sampleRate, WavFileHelpers::canonicalWavChannelSet (static_cast<int> (numChannels)),
2017 bitsPerSample, metadataValues, qualityOptionIndex);
2018}
2019
2021 double sampleRate,
2022 const AudioChannelSet& channelLayout,
2023 int bitsPerSample,
2024 const StringPairArray& metadataValues,
2025 int /*qualityOptionIndex*/)
2026{
2027 if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample) && isChannelLayoutSupported (channelLayout))
2028 return new WavAudioFormatWriter (out, sampleRate, channelLayout,
2029 (unsigned int) bitsPerSample, metadataValues);
2030
2031 return nullptr;
2032}
2033
2034namespace WavFileHelpers
2035{
2036 static bool slowCopyWavFileWithNewMetadata (const File& file, const StringPairArray& metadata)
2037 {
2038 TemporaryFile tempFile (file);
2039 WavAudioFormat wav;
2040
2041 std::unique_ptr<AudioFormatReader> reader (wav.createReaderFor (file.createInputStream().release(), true));
2042
2043 if (reader != nullptr)
2044 {
2045 std::unique_ptr<OutputStream> outStream (tempFile.getFile().createOutputStream());
2046
2047 if (outStream != nullptr)
2048 {
2049 std::unique_ptr<AudioFormatWriter> writer (wav.createWriterFor (outStream.get(), reader->sampleRate,
2050 reader->numChannels, (int) reader->bitsPerSample,
2051 metadata, 0));
2052
2053 if (writer != nullptr)
2054 {
2055 outStream.release();
2056
2057 bool ok = writer->writeFromAudioReader (*reader, 0, -1);
2058 writer.reset();
2059 reader.reset();
2060
2061 return ok && tempFile.overwriteTargetFileWithTemporary();
2062 }
2063 }
2064 }
2065
2066 return false;
2067 }
2068}
2069
2070bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata)
2071{
2072 using namespace WavFileHelpers;
2073
2074 std::unique_ptr<WavAudioFormatReader> reader (static_cast<WavAudioFormatReader*> (createReaderFor (wavFile.createInputStream().release(), true)));
2075
2076 if (reader != nullptr)
2077 {
2078 auto bwavPos = reader->bwavChunkStart;
2079 auto bwavSize = reader->bwavSize;
2080 reader.reset();
2081
2082 if (bwavSize > 0)
2083 {
2084 auto chunk = BWAVChunk::createFrom (toMap (newMetadata));
2085
2086 if (chunk.getSize() <= (size_t) bwavSize)
2087 {
2088 // the new one will fit in the space available, so write it directly..
2089 auto oldSize = wavFile.getSize();
2090
2091 {
2092 FileOutputStream out (wavFile);
2093
2094 if (out.openedOk())
2095 {
2096 out.setPosition (bwavPos);
2097 out << chunk;
2098 out.setPosition (oldSize);
2099 }
2100 }
2101
2102 jassert (wavFile.getSize() == oldSize);
2103 return true;
2104 }
2105 }
2106 }
2107
2108 return slowCopyWavFileWithNewMetadata (wavFile, newMetadata);
2109}
2110
2111
2112//==============================================================================
2113//==============================================================================
2114#if JUCE_UNIT_TESTS
2115
2116struct WaveAudioFormatTests : public UnitTest
2117{
2118 WaveAudioFormatTests()
2119 : UnitTest ("Wave audio format tests", UnitTestCategories::audio)
2120 {}
2121
2122 void runTest() override
2123 {
2124 beginTest ("Setting up metadata");
2125
2126 auto metadataValues = toMap (WavAudioFormat::createBWAVMetadata ("description",
2127 "originator",
2128 "originatorRef",
2129 Time::getCurrentTime(),
2130 numTestAudioBufferSamples,
2131 "codingHistory"));
2132
2133 for (int i = numElementsInArray (WavFileHelpers::ListInfoChunk::types); --i >= 0;)
2134 metadataValues[WavFileHelpers::ListInfoChunk::types[i]] = WavFileHelpers::ListInfoChunk::types[i];
2135
2136 metadataValues[WavAudioFormat::internationalStandardRecordingCode] = WavAudioFormat::internationalStandardRecordingCode;
2137
2138 if (metadataValues.size() > 0)
2139 metadataValues["MetaDataSource"] = "WAV";
2140
2141 const auto smplMetadata = createDefaultSMPLMetadata();
2142 metadataValues.insert (smplMetadata.cbegin(), smplMetadata.cend());
2143
2144 WavAudioFormat format;
2145 MemoryBlock memoryBlock;
2146
2147 StringPairArray metadataArray;
2148 metadataArray.addUnorderedMap (metadataValues);
2149
2150 {
2151 beginTest ("Metadata can be written and read");
2152
2153 const auto newMetadata = getMetadataAfterReading (format, writeToBlock (format, metadataArray));
2154 expect (newMetadata == metadataArray, "Somehow, the metadata is different!");
2155 }
2156
2157 {
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] == "");
2168 }
2169
2170 {
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");
2180 }
2181
2182 {
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");
2193 }
2194
2195 {
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");
2205 }
2206
2207 {
2208 beginTest ("Files containing ASWG metadata read and write correctly");
2209 MemoryBlock block;
2210 StringPairArray meta;
2211
2212 for (const auto& key : WavFileHelpers::IXMLChunk::aswgMetadataKeys)
2213 meta.set (key, "Test123&<>");
2214
2215 {
2216 auto writer = rawToUniquePtr (WavAudioFormat().createWriterFor (new MemoryOutputStream (block, false), 48000, 1, 32, meta, 0));
2217 expect (writer != nullptr);
2218 }
2219
2220 expect ([&]
2221 {
2222 auto input = std::make_unique<MemoryInputStream> (block, false);
2223
2224 while (! input->isExhausted())
2225 {
2226 char chunkType[4] {};
2227 auto pos = input->getPosition();
2228
2229 input->read (chunkType, 4);
2230
2231 if (memcmp (chunkType, "iXML", 4) == 0)
2232 {
2233 auto length = (uint32) input->readInt();
2234
2235 MemoryBlock xmlBlock;
2236 input->readIntoMemoryBlock (xmlBlock, (ssize_t) length);
2237
2238 return parseXML (xmlBlock.toString()) != nullptr;
2239 }
2240
2241 input->setPosition (pos + 1);
2242 }
2243
2244 return false;
2245 }());
2246
2247 {
2248 auto reader = rawToUniquePtr (WavAudioFormat().createReaderFor (new MemoryInputStream (block, false), true));
2249 expect (reader != nullptr);
2250
2251 for (const auto& key : meta.getAllKeys())
2252 {
2253 const auto oldValue = meta.getValue (key, "!");
2254 const auto newValue = reader->metadataValues.getValue (key, "");
2255 expectEquals (oldValue, newValue);
2256 }
2257
2258 expect (reader->metadataValues.getValue (WavAudioFormat::aswgVersion, "") == "3.01");
2259 }
2260 }
2261 }
2262
2263private:
2264 MemoryBlock writeToBlock (WavAudioFormat& format, StringPairArray meta)
2265 {
2266 MemoryBlock mb;
2267
2268 {
2269 // The destructor of the writer will modify the block, so make sure that we've
2270 // destroyed the writer before returning the block!
2271 auto writer = rawToUniquePtr (format.createWriterFor (new MemoryOutputStream (mb, false),
2272 44100.0,
2273 numTestAudioBufferChannels,
2274 16,
2275 meta,
2276 0));
2277 expect (writer != nullptr);
2278 AudioBuffer<float> buffer (numTestAudioBufferChannels, numTestAudioBufferSamples);
2279 expect (writer->writeFromAudioSampleBuffer (buffer, 0, numTestAudioBufferSamples));
2280 }
2281
2282 return mb;
2283 }
2284
2285 StringPairArray getMetadataAfterReading (WavAudioFormat& format, const MemoryBlock& mb)
2286 {
2287 auto reader = rawToUniquePtr (format.createReaderFor (new MemoryInputStream (mb, false), true));
2288 expect (reader != nullptr);
2289 return reader->metadataValues;
2290 }
2291
2292 template <typename Fn>
2293 void checkPatterns (const MemoryBlock& mb, const std::vector<std::string>& patterns, Fn&& fn)
2294 {
2295 for (const auto& pattern : patterns)
2296 {
2297 const auto begin = static_cast<const char*> (mb.getData());
2298 const auto end = begin + mb.getSize();
2299 expect (fn (std::search (begin, end, pattern.begin(), pattern.end()), end));
2300 }
2301 }
2302
2303 void checkPatternsPresent (const MemoryBlock& mb, const std::vector<std::string>& patterns)
2304 {
2305 checkPatterns (mb, patterns, std::not_equal_to<>{});
2306 }
2307
2308 void checkPatternsNotPresent (const MemoryBlock& mb, const std::vector<std::string>& patterns)
2309 {
2310 checkPatterns (mb, patterns, std::equal_to<>{});
2311 }
2312
2313 enum
2314 {
2315 numTestAudioBufferChannels = 2,
2316 numTestAudioBufferSamples = 256
2317 };
2318
2319 static StringMap createDefaultSMPLMetadata()
2320 {
2321 StringMap m;
2322
2323 m["Manufacturer"] = "0";
2324 m["Product"] = "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";
2332
2333 return m;
2334 }
2335
2336 JUCE_DECLARE_NON_COPYABLE (WaveAudioFormatTests)
2337};
2338
2339static const WaveAudioFormatTests waveAudioFormatTests;
2340
2341#endif
2342
2343} // namespace juce
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
AudioFormat(String formatName, StringArray fileExtensions)
Definition juce_AudioFormat.cpp:29
Definition juce_AudioFormatReader.h:44
InputStream * input
Definition juce_AudioFormatReader.h:248
bool usesFloatingPointData
Definition juce_AudioFormatReader.h:237
StringPairArray metadataValues
Definition juce_AudioFormatReader.h:245
static void clearSamplesBeyondAvailableLength(int **destChannels, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int &numSamples, int64 fileLengthInSamples)
Definition juce_AudioFormatReader.h:309
int64 lengthInSamples
Definition juce_AudioFormatReader.h:231
double sampleRate
Definition juce_AudioFormatReader.h:225
AudioFormatReader(InputStream *sourceStream, const String &formatName)
Definition juce_AudioFormatReader.cpp:29
unsigned int bitsPerSample
Definition juce_AudioFormatReader.h:228
virtual void readMaxLevels(int64 startSample, int64 numSamples, Range< float > *results, int numChannelsToRead)
Definition juce_AudioFormatReader.cpp:209
unsigned int numChannels
Definition juce_AudioFormatReader.h:234
Definition juce_AudioFormatWriter.h:44
unsigned int numChannels
Definition juce_AudioFormatWriter.h:251
double sampleRate
Definition juce_AudioFormatWriter.h:248
bool usesFloatingPointData
Definition juce_AudioFormatWriter.h:257
unsigned int bitsPerSample
Definition juce_AudioFormatWriter.h:254
AudioFormatWriter(OutputStream *destStream, const String &formatName, double sampleRate, unsigned int numberOfChannels, unsigned int bitsPerSample)
Definition juce_AudioFormatWriter.cpp:29
AudioChannelSet channelLayout
Definition juce_AudioFormatWriter.h:260
OutputStream * output
Definition juce_AudioFormatWriter.h:263
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_FileInputStream.h:35
const File & getFile() const noexcept
Definition juce_FileInputStream.h:51
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_InputStream.h:37
virtual int64 getPosition()=0
virtual size_t readIntoMemoryBlock(MemoryBlock &destBlock, ssize_t maxNumBytesToRead=-1)
Definition juce_InputStream.cpp:223
virtual int read(void *destBuffer, int maxBytesToRead)=0
virtual int readInt()
Definition juce_InputStream.cpp:88
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_MemoryMappedAudioFormatReader.h:47
MemoryMappedAudioFormatReader(const File &file, const AudioFormatReader &details, int64 dataChunkStart, int64 dataChunkLength, int bytesPerFrame)
Definition juce_AudioFormatReader.cpp:404
int64 dataLength
Definition juce_MemoryMappedAudioFormatReader.h:88
Range< int64 > mappedSection
Definition juce_MemoryMappedAudioFormatReader.h:86
std::unique_ptr< MemoryMappedFile > map
Definition juce_MemoryMappedAudioFormatReader.h:87
int64 dataChunkStart
Definition juce_MemoryMappedAudioFormatReader.h:88
int bytesPerFrame
Definition juce_MemoryMappedAudioFormatReader.h:89
const void * sampleToPointer(int64 sample) const noexcept
Definition juce_MemoryMappedAudioFormatReader.h:98
Range< float > scanMinAndMaxInterleaved(int channel, int64 startSampleInFile, int64 numSamples) const noexcept
Definition juce_MemoryMappedAudioFormatReader.h:102
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_WavAudioFormat.h:38
static const char *const aswgRecStudio
Definition juce_WavAudioFormat.h:201
static const char *const aswgBillingCode
Definition juce_WavAudioFormat.h:263
static const char *const aswgMicDistance
Definition juce_WavAudioFormat.h:197
static const char *const riffInfoCopyright
Definition juce_WavAudioFormat.h:104
static const char *const acidRootSet
Definition juce_WavAudioFormat.h:83
static const char *const aswgUserData
Definition juce_WavAudioFormat.h:207
static const char *const riffInfoDirectory
Definition juce_WavAudioFormat.h:112
static const char *const bwavCodingHistory
Definition juce_WavAudioFormat.h:55
static const char *const bwavTimeReference
Definition juce_WavAudioFormat.h:65
static const char *const acidDiskBased
Definition juce_WavAudioFormat.h:85
static const char *const aswgEfforts
Definition juce_WavAudioFormat.h:221
static const char *const aswgMusicSup
Definition juce_WavAudioFormat.h:245
static const char *const aswgTimeSig
Definition juce_WavAudioFormat.h:261
static const char *const acidOneShot
Definition juce_WavAudioFormat.h:82
static const char *const aswgIsDesigned
Definition juce_WavAudioFormat.h:199
static const char *const riffInfoOrganisation
Definition juce_WavAudioFormat.h:139
static const char *const aswgCharacterName
Definition juce_WavAudioFormat.h:226
static const char *const aswgIsUnion
Definition juce_WavAudioFormat.h:236
static const char *const aswgLibrary
Definition juce_WavAudioFormat.h:210
static const char *const riffInfoFirstLanguage
Definition juce_WavAudioFormat.h:121
static const char *const aswgAmbisonicChnOrder
Definition juce_WavAudioFormat.h:193
static const char *const aswgRecordingLoc
Definition juce_WavAudioFormat.h:198
static const char *const aswgCreatorId
Definition juce_WavAudioFormat.h:211
static const char *const riffInfoEncodedBy
Definition juce_WavAudioFormat.h:117
static const char *const riffInfoCommissioned
Definition juce_WavAudioFormat.h:103
static const char *const riffInfoMusicBy
Definition juce_WavAudioFormat.h:136
static const char *const riffInfoSharpness
Definition juce_WavAudioFormat.h:152
static const char *const aswgProducer
Definition juce_WavAudioFormat.h:244
static const char *const aswgFxUsed
Definition juce_WavAudioFormat.h:234
static const char *const riffInfoStatistics
Definition juce_WavAudioFormat.h:161
static const char *const riffInfoNinthLanguage
Definition juce_WavAudioFormat.h:137
static const char *const riffInfoDefaultAudioStream
Definition juce_WavAudioFormat.h:110
static const char *const riffInfoGenre
Definition juce_WavAudioFormat.h:123
bool canDoMono() override
Definition juce_WavAudioFormat.cpp:1955
static const char *const riffInfoMoreInfoBannerImage
Definition juce_WavAudioFormat.h:132
static const char *const aswgProjection
Definition juce_WavAudioFormat.h:223
static const char *const riffInfoVegasVersionMajor
Definition juce_WavAudioFormat.h:171
static const char *const aswgContentType
Definition juce_WavAudioFormat.h:181
static const char *const aswgOriginator
Definition juce_WavAudioFormat.h:183
static const char *const riffInfoLocation
Definition juce_WavAudioFormat.h:128
static const char *const aswgIsOst
Definition juce_WavAudioFormat.h:254
AudioFormatReader * createReaderFor(InputStream *sourceStream, bool deleteStreamIfOpeningFails) override
Definition juce_WavAudioFormat.cpp:1973
static const char *const aswgRmsPower
Definition juce_WavAudioFormat.h:213
static const char *const riffInfoRate
Definition juce_WavAudioFormat.h:145
static const char *const riffInfoCostumeDesigner
Definition juce_WavAudioFormat.h:105
static const char *const riffInfoVersion
Definition juce_WavAudioFormat.h:173
static const char *const aswgActorGender
Definition juce_WavAudioFormat.h:231
static const char *const riffInfoLightness
Definition juce_WavAudioFormat.h:127
static const char *const riffInfoProductionStudio
Definition juce_WavAudioFormat.h:144
static const char *const aswgIsLoop
Definition juce_WavAudioFormat.h:250
static const char *const aswgState
Definition juce_WavAudioFormat.h:187
static const char *const aswgSongTitle
Definition juce_WavAudioFormat.h:241
static const char *const riffInfoProducedBy
Definition juce_WavAudioFormat.h:141
static const char *const aswgSpecDensity
Definition juce_WavAudioFormat.h:217
static const char *const riffInfoEighthLanguage
Definition juce_WavAudioFormat.h:116
static const char *const riffInfoCropped
Definition juce_WavAudioFormat.h:107
static const char *const aswgCharacterAge
Definition juce_WavAudioFormat.h:228
bool canDoStereo() override
Definition juce_WavAudioFormat.cpp:1954
static const char *const riffInfoRating
Definition juce_WavAudioFormat.h:147
static const char *const aswgMicType
Definition juce_WavAudioFormat.h:195
static const char *const aswgIsDiegetic
Definition juce_WavAudioFormat.h:257
static const char *const riffInfoURL
Definition juce_WavAudioFormat.h:170
static const char *const aswgVersion
Definition juce_WavAudioFormat.h:264
static const char *const ISRC
Definition juce_WavAudioFormat.h:269
static const char *const riffInfoMoreInfoBannerURL
Definition juce_WavAudioFormat.h:133
static const char *const riffInfoStartTimecode
Definition juce_WavAudioFormat.h:160
static const char *const aswgLoudnessRange
Definition juce_WavAudioFormat.h:215
static const char *const bwavOriginatorRef
Definition juce_WavAudioFormat.h:52
static const char *const aswgChannelConfig
Definition juce_WavAudioFormat.h:191
static const char *const riffInfoTitle
Definition juce_WavAudioFormat.h:167
static const char *const aswgIsFinal
Definition juce_WavAudioFormat.h:252
static const char *const riffInfoArtist
Definition juce_WavAudioFormat.h:97
static const char *const aswgMusicPublisher
Definition juce_WavAudioFormat.h:247
static const char *const riffInfoSixthLanguage
Definition juce_WavAudioFormat.h:153
static const char *const riffInfoSecondaryGenre
Definition juce_WavAudioFormat.h:149
static const char *const riffInfoFifthLanguage
Definition juce_WavAudioFormat.h:120
static const char *const riffInfoDotsPerInch
Definition juce_WavAudioFormat.h:114
static const char *const riffInfoDistributedBy
Definition juce_WavAudioFormat.h:113
static const char *const riffInfoStarring_ISTR
Definition juce_WavAudioFormat.h:158
static const char *const aswgAccent
Definition juce_WavAudioFormat.h:237
static const char *const riffInfoProductName
Definition juce_WavAudioFormat.h:142
static const char *const riffInfoKeywords
Definition juce_WavAudioFormat.h:124
static const char *const aswgInstrument
Definition juce_WavAudioFormat.h:246
static const char *const aswgSession
Definition juce_WavAudioFormat.h:186
static const char *const riffInfoRippedBy
Definition juce_WavAudioFormat.h:148
static const char *const riffInfoLanguage
Definition juce_WavAudioFormat.h:125
static const char *const riffInfoDateTimeOriginal
Definition juce_WavAudioFormat.h:109
static const char *const acidizerFlag
Definition juce_WavAudioFormat.h:86
static const char *const riffInfoBaseURL
Definition juce_WavAudioFormat.h:98
MemoryMappedAudioFormatReader * createMemoryMappedReader(const File &) override
Definition juce_WavAudioFormat.cpp:1994
bool isChannelLayoutSupported(const AudioChannelSet &channelSet) override
Definition juce_WavAudioFormat.cpp:1957
static const char *const aswgArtist
Definition juce_WavAudioFormat.h:240
static const char *const riffInfoProductionDesigner
Definition juce_WavAudioFormat.h:143
static const char *const acidDenominator
Definition juce_WavAudioFormat.h:89
static const char *const aswgCharacterRole
Definition juce_WavAudioFormat.h:229
static const char *const aswgDirection
Definition juce_WavAudioFormat.h:233
static const char *const aswgIsSource
Definition juce_WavAudioFormat.h:249
static const char *const aswgFxChainName
Definition juce_WavAudioFormat.h:190
static const char *const aswgFxName
Definition juce_WavAudioFormat.h:209
static const char *const aswgOriginatorStudio
Definition juce_WavAudioFormat.h:184
static const char *const riffInfoVegasVersionMinor
Definition juce_WavAudioFormat.h:172
static const char *const riffInfoLength
Definition juce_WavAudioFormat.h:126
bool replaceMetadataInFile(const File &wavFile, const StringPairArray &newMetadata)
Definition juce_WavAudioFormat.cpp:2070
static const char *const aswgUsageRights
Definition juce_WavAudioFormat.h:235
~WavAudioFormat() override
Definition juce_WavAudioFormat.cpp:1941
static const char *const riffInfoTechnician
Definition juce_WavAudioFormat.h:164
static const char *const riffInfoSoftware
Definition juce_WavAudioFormat.h:154
static const char *const riffInfoStarring_STAR
Definition juce_WavAudioFormat.h:159
static const char *const riffInfoDateCreated
Definition juce_WavAudioFormat.h:108
static const char *const riffInfoSeventhLanguage
Definition juce_WavAudioFormat.h:151
static const char *const aswgActorName
Definition juce_WavAudioFormat.h:230
static const char *const aswgAmbisonicFormat
Definition juce_WavAudioFormat.h:192
static const char *const acidBeats
Definition juce_WavAudioFormat.h:88
static const char *const aswgMusicVersion
Definition juce_WavAudioFormat.h:258
AudioFormatWriter * createWriterFor(OutputStream *streamToWriteTo, double sampleRateToUse, unsigned int numberOfChannels, int bitsPerSample, const StringPairArray &metadataValues, int qualityOptionIndex) override
Definition juce_WavAudioFormat.cpp:2012
static const char *const aswgMixer
Definition juce_WavAudioFormat.h:189
static const char *const riffInfoLogoIconURL
Definition juce_WavAudioFormat.h:129
static const char *const tracktionLoopInfo
Definition juce_WavAudioFormat.h:275
static const char *const acidNumerator
Definition juce_WavAudioFormat.h:90
static const char *const bwavOriginationDate
Definition juce_WavAudioFormat.h:53
static const char *const internationalStandardRecordingCode
Definition juce_WavAudioFormat.h:272
static const char *const aswgSourceId
Definition juce_WavAudioFormat.h:212
static const char *const riffInfoComments
Definition juce_WavAudioFormat.h:102
static const char *const riffInfoNumberOfParts
Definition juce_WavAudioFormat.h:138
static const char *const aswgVendorCategory
Definition juce_WavAudioFormat.h:208
static const char *const bwavDescription
Definition juce_WavAudioFormat.h:50
static const char *const riffInfoSoundSchemeTitle
Definition juce_WavAudioFormat.h:155
static const char *const aswgPapr
Definition juce_WavAudioFormat.h:219
Array< int > getPossibleSampleRates() override
Definition juce_WavAudioFormat.cpp:1943
static const char *const aswgEditor
Definition juce_WavAudioFormat.h:188
static const char *const aswgComposor
Definition juce_WavAudioFormat.h:239
static const char *const aswgSubGenre
Definition juce_WavAudioFormat.h:243
static const char *const aswgEffortType
Definition juce_WavAudioFormat.h:222
static const char *const riffInfoWatermarkURL
Definition juce_WavAudioFormat.h:174
static const char *const aswgLoudness
Definition juce_WavAudioFormat.h:214
static const char *const riffInfoTrackNo
Definition juce_WavAudioFormat.h:168
static const char *const riffInfoMedium
Definition juce_WavAudioFormat.h:131
static const char *const acidStretch
Definition juce_WavAudioFormat.h:84
Array< int > getPossibleBitDepths() override
Definition juce_WavAudioFormat.cpp:1949
static const char *const aswgRightsOwner
Definition juce_WavAudioFormat.h:248
static const char *const aswgImpulseLocation
Definition juce_WavAudioFormat.h:202
static const char *const riffInfoThirdLanguage
Definition juce_WavAudioFormat.h:165
static const char *const bwavOriginationTime
Definition juce_WavAudioFormat.h:54
static const char *const aswgLanguage
Definition juce_WavAudioFormat.h:224
static const char *const riffInfoArchivalLocation
Definition juce_WavAudioFormat.h:96
static const char *const aswgTimingRestriction
Definition juce_WavAudioFormat.h:225
static const char *const aswgIsrcId
Definition juce_WavAudioFormat.h:259
static const char *const aswgIsLicensed
Definition juce_WavAudioFormat.h:256
static const char *const aswgCategory
Definition juce_WavAudioFormat.h:203
static const char *const aswgZeroCrossRate
Definition juce_WavAudioFormat.h:218
static const char *const aswgGenre
Definition juce_WavAudioFormat.h:242
static const char *const aswgMaxPeak
Definition juce_WavAudioFormat.h:216
static const char *const riffInfoMoreInfoText
Definition juce_WavAudioFormat.h:134
static const char *const aswgCharacterGender
Definition juce_WavAudioFormat.h:227
static const char *const riffInfoCinematographer
Definition juce_WavAudioFormat.h:99
static const char *const riffInfoFourthLanguage
Definition juce_WavAudioFormat.h:122
static const char *const riffInfoSubject
Definition juce_WavAudioFormat.h:162
static const char *const aswgEmotion
Definition juce_WavAudioFormat.h:238
static const char *const aswgInKey
Definition juce_WavAudioFormat.h:262
static const char *const aswgMicConfig
Definition juce_WavAudioFormat.h:196
static const char *const riffInfoRated
Definition juce_WavAudioFormat.h:146
static const char *const riffInfoDimension
Definition juce_WavAudioFormat.h:111
static const char *const aswgProject
Definition juce_WavAudioFormat.h:182
static const char *const aswgIntensity
Definition juce_WavAudioFormat.h:251
static const char *const riffInfoEditedBy
Definition juce_WavAudioFormat.h:115
static const char *const riffInfoYear
Definition juce_WavAudioFormat.h:176
static const char *const riffInfoComment2
Definition juce_WavAudioFormat.h:101
static StringPairArray createBWAVMetadata(const String &description, const String &originator, const String &originatorRef, Time dateAndTime, int64 timeReferenceSamples, const String &codingHistory)
Definition juce_WavAudioFormat.cpp:58
static const char *const riffInfoTrackNumber
Definition juce_WavAudioFormat.h:169
static const char *const riffInfoEngineer
Definition juce_WavAudioFormat.h:119
static const char *const riffInfoWrittenBy
Definition juce_WavAudioFormat.h:175
static const char *const aswgSubCategory
Definition juce_WavAudioFormat.h:204
static const char *const aswgText
Definition juce_WavAudioFormat.h:220
static const char *const riffInfoTimeCode
Definition juce_WavAudioFormat.h:166
static const char *const riffInfoSourceFrom
Definition juce_WavAudioFormat.h:157
static const char *const riffInfoSource
Definition juce_WavAudioFormat.h:156
static const char *const riffInfoLogoURL
Definition juce_WavAudioFormat.h:130
static const char *const aswgOrderRef
Definition juce_WavAudioFormat.h:253
static const char *const riffInfoCountry
Definition juce_WavAudioFormat.h:106
static const char *const aswgAmbisonicNorm
Definition juce_WavAudioFormat.h:194
static const char *const aswgUserCategory
Definition juce_WavAudioFormat.h:206
static const char *const aswgNotes
Definition juce_WavAudioFormat.h:185
static const char *const riffInfoSecondLanguage
Definition juce_WavAudioFormat.h:150
static const char *const aswgTempo
Definition juce_WavAudioFormat.h:260
static const char *const riffInfoComment
Definition juce_WavAudioFormat.h:100
static const char *const riffInfoTapeName
Definition juce_WavAudioFormat.h:163
static const char *const aswgDirector
Definition juce_WavAudioFormat.h:232
static const char *const aswgRecEngineer
Definition juce_WavAudioFormat.h:200
static const char *const aswgCatId
Definition juce_WavAudioFormat.h:205
static const char *const riffInfoEndTimecode
Definition juce_WavAudioFormat.h:118
static const char *const aswgIsCinematic
Definition juce_WavAudioFormat.h:255
WavAudioFormat()
Definition juce_WavAudioFormat.cpp:1940
static const char *const riffInfoPart
Definition juce_WavAudioFormat.h:140
static const char *const bwavOriginator
Definition juce_WavAudioFormat.h:51
static const char *const acidTempo
Definition juce_WavAudioFormat.h:91
static const char *const acidRootNote
Definition juce_WavAudioFormat.h:87
static const char *const riffInfoMoreInfoURL
Definition juce_WavAudioFormat.h:135
Definition juce_WavAudioFormat.cpp:1208
bool isRF64
Definition juce_WavAudioFormat.cpp:1572
static AudioChannelSet getChannelLayoutFromMask(int dwChannelMask, size_t totalNumChannels)
Definition juce_WavAudioFormat.cpp:1540
bool readSamples(int **destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override
Definition juce_WavAudioFormat.cpp:1479
bool isSubformatOggVorbis
Definition juce_WavAudioFormat.cpp:1573
int64 bwavChunkStart
Definition juce_WavAudioFormat.cpp:1569
int bytesPerFrame
Definition juce_WavAudioFormat.cpp:1571
int64 dataLength
Definition juce_WavAudioFormat.cpp:1570
AudioChannelSet channelLayout
Definition juce_WavAudioFormat.cpp:1575
AudioChannelSet getChannelLayout() override
Definition juce_WavAudioFormat.cpp:1532
static void copySampleData(unsigned int numBitsPerSample, const bool floatingPointData, int *const *destSamples, int startOffsetInDestBuffer, int numDestChannels, const void *sourceData, int numberOfChannels, int numSamples) noexcept
Definition juce_WavAudioFormat.cpp:1515
int64 dataChunkStart
Definition juce_WavAudioFormat.cpp:1570
WavAudioFormatReader(InputStream *in)
Definition juce_WavAudioFormat.cpp:1210
int64 bwavSize
Definition juce_WavAudioFormat.cpp:1569
Definition juce_WavAudioFormat.cpp:1583
MemoryBlock bwavChunk
Definition juce_WavAudioFormat.cpp:1673
void writeHeader()
Definition juce_WavAudioFormat.cpp:1678
uint64 bytesWritten
Definition juce_WavAudioFormat.cpp:1674
void writeChunk(const MemoryBlock &data, int chunkType, int size=0) const
Definition juce_WavAudioFormat.cpp:1809
bool flush() override
Definition juce_WavAudioFormat.cpp:1658
MemoryBlock listInfoChunk
Definition juce_WavAudioFormat.cpp:1673
MemoryBlock trckChunk
Definition juce_WavAudioFormat.cpp:1673
bool writeFailed
Definition juce_WavAudioFormat.cpp:1676
~WavAudioFormatWriter() override
Definition juce_WavAudioFormat.cpp:1617
MemoryBlock instChunk
Definition juce_WavAudioFormat.cpp:1673
uint64 lengthInSamples
Definition juce_WavAudioFormat.cpp:1674
int64 headerPosition
Definition juce_WavAudioFormat.cpp:1675
MemoryBlock cueChunk
Definition juce_WavAudioFormat.cpp:1673
MemoryBlock ixmlChunk
Definition juce_WavAudioFormat.cpp:1673
MemoryBlock listChunk
Definition juce_WavAudioFormat.cpp:1673
static int getChannelMaskFromChannelLayout(const AudioChannelSet &layout)
Definition juce_WavAudioFormat.cpp:1818
WavAudioFormatWriter(OutputStream *const out, const double rate, const AudioChannelSet &channelLayoutToUse, const unsigned int bits, const StringPairArray &metadataValues)
Definition juce_WavAudioFormat.cpp:1585
static size_t chunkSize(const MemoryBlock &data) noexcept
Definition juce_WavAudioFormat.cpp:1801
bool write(const int **data, int numSamples) override
Definition juce_WavAudioFormat.cpp:1623
MemoryBlock acidChunk
Definition juce_WavAudioFormat.cpp:1673
MemoryBlock axmlChunk
Definition juce_WavAudioFormat.cpp:1673
MemoryBlock smplChunk
Definition juce_WavAudioFormat.cpp:1673
MemoryBlock tempBlock
Definition juce_WavAudioFormat.cpp:1673
void writeChunkHeader(int chunkType, int size) const
Definition juce_WavAudioFormat.cpp:1803
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
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE(className)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
#define jassertfalse
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
Definition juce_AudioFormatReader.h:282
Definition juce_AudioFormatWriter.h:268
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:1175
uint32 data1
Definition juce_WavAudioFormat.cpp:1176
uint8 data4[8]
Definition juce_WavAudioFormat.cpp:1179
uint16 data2
Definition juce_WavAudioFormat.cpp:1177
uint16 data3
Definition juce_WavAudioFormat.cpp:1178
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
b
Definition crypt.c:628
ulg size
Definition extract.c:2350
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