| @@ -194,6 +194,50 @@ namespace AiffFileHelpers | |||||
| #pragma pack (pop) | #pragma pack (pop) | ||||
| #endif | #endif | ||||
| //============================================================================== | |||||
| static String readCATEChunk (InputStream& input, const uint32 length) | |||||
| { | |||||
| MemoryBlock mb; | |||||
| input.skipNextBytes (4); | |||||
| input.readIntoMemoryBlock (mb, length - 4); | |||||
| static const char* appleGenres[] = | |||||
| { | |||||
| "Rock/Blues", | |||||
| "Electronic/Dance", | |||||
| "Jazz", | |||||
| "Urban", | |||||
| "World/Ethnic", | |||||
| "Cinematic/New Age", | |||||
| "Orchestral", | |||||
| "Country/Folk", | |||||
| "Experimental", | |||||
| "Other Genre", | |||||
| nullptr | |||||
| }; | |||||
| const StringArray genres (appleGenres); | |||||
| StringArray tagsArray; | |||||
| int bytesLeft = (int) mb.getSize(); | |||||
| const char* data = static_cast <const char*> (mb.getData()); | |||||
| while (bytesLeft > 0) | |||||
| { | |||||
| const String tag (CharPointer_UTF8 (data), | |||||
| CharPointer_UTF8 (data + bytesLeft)); | |||||
| if (tag.isNotEmpty()) | |||||
| tagsArray.add (data); | |||||
| const int numBytesInTag = genres.contains (tag) ? 118 : 50; | |||||
| data += numBytesInTag; | |||||
| bytesLeft -= numBytesInTag; | |||||
| } | |||||
| return tagsArray.joinIntoString (";"); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| namespace MarkChunk | namespace MarkChunk | ||||
| { | { | ||||
| @@ -473,6 +517,11 @@ public: | |||||
| { | { | ||||
| AiffFileHelpers::BASCChunk (*input).addToMetadata (metadataValues); | AiffFileHelpers::BASCChunk (*input).addToMetadata (metadataValues); | ||||
| } | } | ||||
| else if (type == chunkName ("cate")) | |||||
| { | |||||
| metadataValues.set (AiffAudioFormat::appleTag, | |||||
| AiffFileHelpers::readCATEChunk (*input, length));; | |||||
| } | |||||
| else if ((hasGotVer && hasGotData && hasGotType) | else if ((hasGotVer && hasGotData && hasGotType) | ||||
| || chunkEnd < input->getPosition() | || chunkEnd < input->getPosition() | ||||
| || input->isExhausted()) | || input->isExhausted()) | ||||