From ffa367a3eb3d96745422c590caec885b12fe19ff Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 20 Sep 2013 09:45:59 +0100 Subject: [PATCH] Added key signature detection to CoreAudioFormat. --- .../codecs/juce_CoreAudioFormat.cpp | 36 +++++++++++++++++++ .../codecs/juce_CoreAudioFormat.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp index 89345b58da..8195242c54 100644 --- a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp @@ -53,6 +53,7 @@ namespace const char* const CoreAudioFormat::midiDataBase64 = "midiDataBase64"; const char* const CoreAudioFormat::tempo = "tempo"; const char* const CoreAudioFormat::timeSig = "time signature"; +const char* const CoreAudioFormat::keySig = "key signature"; //============================================================================== struct CoreAudioFormatMetatdata @@ -143,6 +144,7 @@ struct CoreAudioFormatMetatdata findTempoEvents (midiFile, midiMetadata); findTimeSigEvents (midiFile, midiMetadata); + findKeySigEvents (midiFile, midiMetadata); } input.setPosition (originalPosition + size); @@ -220,6 +222,40 @@ struct CoreAudioFormatMetatdata midiMetadata.set ("time signature sequence", timeSigSequence.toUTF8()); } + static void findKeySigEvents (MidiFile& midiFile, StringPairArray& midiMetadata) + { + MidiMessageSequence keySigEvents; + midiFile.findAllKeySigEvents (keySigEvents); + const int numKeySigEvents = keySigEvents.getNumEvents(); + + MemoryOutputStream keySigSequence; + + for (int i = 0; i < numKeySigEvents; ++i) + { + const MidiMessage& message (keySigEvents.getEventPointer (i)->message); + const int key = jlimit (0, 14, message.getKeySignatureNumberOfSharpsOrFlats() + 7); + const bool isMajor = message.isKeySignatureMajorKey(); + + static const char* majorKeys[] = { "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#" }; + static const char* minorKeys[] = { "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#" }; + + String keySigString (isMajor ? majorKeys[key] + : minorKeys[key]); + + if (! isMajor) + keySigString << 'm'; + + if (i == 0) + midiMetadata.set (CoreAudioFormat::keySig, keySigString); + + if (numKeySigEvents > 1) + keySigSequence << keySigString << ',' << keySigEvents.getEventTime (i) << ';'; + } + + if (keySigSequence.getDataSize() > 0) + midiMetadata.set ("key signature sequence", keySigSequence.toUTF8()); + } + //============================================================================== static StringPairArray parseInformationChunk (InputStream& input) { diff --git a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h index 2a439c61fc..60bace485d 100644 --- a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h +++ b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h @@ -50,6 +50,8 @@ public: static const char* const tempo; /** Metadata property name used when reading a caf file time signature information. */ static const char* const timeSig; + /** Metadata property name used when reading a caf file time signature information. */ + static const char* const keySig; //============================================================================== Array getPossibleSampleRates() override;