From 1cda5c60e1db9cc4ec48d0556ac5fc8e52718041 Mon Sep 17 00:00:00 2001 From: louisjb Date: Tue, 8 Sep 2009 20:26:39 +0000 Subject: [PATCH] Now suppress the second accidental in the bar git-svn-id: https://svn.code.sf.net/p/pianobooster/code/trunk@72 ba081f5d-443b-49a7-ac4b-446c3f91f371 --- PianoBooster/src/Bar.cpp | 1 + PianoBooster/src/Bar.h | 4 ++- PianoBooster/src/CMakeLists.txt | 1 - PianoBooster/src/Cfg.h | 1 + PianoBooster/src/Chord.cpp | 14 ++++++--- PianoBooster/src/Chord.h | 8 +++-- PianoBooster/src/Draw.cpp | 3 ++ PianoBooster/src/GuiTopBar.cpp | 4 +-- PianoBooster/src/MidiEvent.h | 5 +-- PianoBooster/src/MidiTrack.cpp | 49 +++++++++++++++++++++++------- PianoBooster/src/MidiTrack.h | 3 +- PianoBooster/src/Notation.cpp | 46 ++++++++++++++++++++++++++-- PianoBooster/src/Notation.h | 30 ++++++++++++++++++ PianoBooster/src/Settings.cpp | 2 +- PianoBooster/src/Song.cpp | 8 +++-- PianoBooster/src/Song.h | 2 +- PianoBooster/src/StavePosition.cpp | 6 +++- PianoBooster/src/StavePosition.h | 10 +++++- PianoBooster/src/Symbol.h | 19 ++++++++++++ PianoBooster/src/TrackList.cpp | 3 +- 20 files changed, 185 insertions(+), 34 deletions(-) diff --git a/PianoBooster/src/Bar.cpp b/PianoBooster/src/Bar.cpp index 2e362cd..a7dddfd 100644 --- a/PianoBooster/src/Bar.cpp +++ b/PianoBooster/src/Bar.cpp @@ -53,6 +53,7 @@ void CBar::setTimeSig(int top, int bottom) } } m_beatLength = (CMidiFile::getPulsesPerQuarterNote() *4)/ m_currentTimeSigBottom; + m_barLength = m_beatLength * getTimeSigTop(); } int CBar::addDeltaTime(int ticks) diff --git a/PianoBooster/src/Bar.h b/PianoBooster/src/Bar.h index bf2e265..8942989 100644 --- a/PianoBooster/src/Bar.h +++ b/PianoBooster/src/Bar.h @@ -57,6 +57,7 @@ public: int getTimeSigTop() {return m_currentTimeSigTop;} // The Numerator int getBeatLength() {return m_beatLength;} + int getBarLength() {return m_barLength;} // in ppqn void setPlayFromBar(double bar); void setPlayFromBar(int bar, int beat = 0, int ticks = 0); @@ -121,7 +122,8 @@ private: int m_deltaTime; - int m_beatLength; + int m_beatLength; //in ppqn ticks + int m_barLength; // m_beatLength * getTimeSigTop() (also in ppqn ticks) int m_startTimeSigTop; // The time Sig at the start of the piece int m_startTimeSigBottom; diff --git a/PianoBooster/src/CMakeLists.txt b/PianoBooster/src/CMakeLists.txt index 98257f0..5ee1ddd 100644 --- a/PianoBooster/src/CMakeLists.txt +++ b/PianoBooster/src/CMakeLists.txt @@ -47,7 +47,6 @@ INCLUDE( ${QT_USE_FILE} ) IF (USE_PCH) INCLUDE(precompile/PCHSupport_26.cmake) INCLUDE_DIRECTORIES( precompile .) - ENDIF(USE_PCH) diff --git a/PianoBooster/src/Cfg.h b/PianoBooster/src/Cfg.h index 21b759f..e9c441e 100644 --- a/PianoBooster/src/Cfg.h +++ b/PianoBooster/src/Cfg.h @@ -74,6 +74,7 @@ public: static int playZoneLate() {return m_playZoneLate;} static int silenceTimeOut() {return 8000;} // the time in msec before everything goes quiet static int chordNoteGap() {return 10;} // all notes in a cord must be spaced less than this a gap + static int chordMaxLength() {return 20;} // the max time between the start and end of a cord static CColour menuColour() {return CColour(0.1, 0.6, 0.6);} diff --git a/PianoBooster/src/Chord.cpp b/PianoBooster/src/Chord.cpp index fbe6086..604b104 100644 --- a/PianoBooster/src/Chord.cpp +++ b/PianoBooster/src/Chord.cpp @@ -168,9 +168,11 @@ bool CFindChord::findChord(CMidiEvent midi, int channel, whichPart_t part) return foundChord; } - m_runningDeltaTime += midi.deltaTime(); + m_noteGapTime += midi.deltaTime(); - if (m_runningDeltaTime >= m_cfg_ChordNoteGap && m_currentChord.length() > 0) + + if ((m_noteGapTime >= m_cfg_ChordNoteGap || m_cordSpanGapTime > m_cfg_ChordMaxLength) + && m_currentChord.length() > 0 ) { foundChord = true; m_completeChord = m_currentChord; @@ -183,8 +185,12 @@ bool CFindChord::findChord(CMidiEvent midi, int channel, whichPart_t part) if ( hand != PB_PART_none) { m_currentChord.addNote(hand, midi.note()); - m_currentChord.setDeltaTime(m_runningDeltaTime + m_currentChord.getDeltaTime()); - m_runningDeltaTime = 0; + m_currentChord.setDeltaTime(m_noteGapTime + m_currentChord.getDeltaTime()); + if (m_currentChord.length() <= 1) + m_cordSpanGapTime = 0; + else + m_cordSpanGapTime += m_noteGapTime; // measure the span of the cord + m_noteGapTime = 0; } } return foundChord; diff --git a/PianoBooster/src/Chord.h b/PianoBooster/src/Chord.h index 67ab36e..ba90d08 100644 --- a/PianoBooster/src/Chord.h +++ b/PianoBooster/src/Chord.h @@ -180,10 +180,12 @@ public: void reset() { - m_runningDeltaTime = 0; + m_noteGapTime = 0; + m_cordSpanGapTime = 0; m_completeChord.clear(); m_currentChord.clear(); m_cfg_ChordNoteGap = CMidiFile::ppqnAdjust(Cfg::chordNoteGap()); + m_cfg_ChordMaxLength = CMidiFile::ppqnAdjust(Cfg::chordMaxLength()); } @@ -197,10 +199,12 @@ public: bool findChord(CMidiEvent midi, int channel, whichPart_t part); private: - int m_runningDeltaTime; + int m_noteGapTime; + int m_cordSpanGapTime; CChord m_currentChord; CChord m_completeChord; int m_cfg_ChordNoteGap; + int m_cfg_ChordMaxLength; }; #endif // __CHORD_H__ diff --git a/PianoBooster/src/Draw.cpp b/PianoBooster/src/Draw.cpp index 78f7970..c2650e4 100644 --- a/PianoBooster/src/Draw.cpp +++ b/PianoBooster/src/Draw.cpp @@ -269,6 +269,9 @@ void CDraw::checkAccidental(CSymbol symbol, float x, float y) accidental = symbol.getStavePos().getAccidental(); + if (symbol.getAccidentalModifer() == PB_ACCIDENTAL_MODIFER_suppress_accidental) + accidental = 0; // Suppress the accidental if it is the same bar + if (accidental != 0) { //drColour (Cfg::lineColour()); diff --git a/PianoBooster/src/GuiTopBar.cpp b/PianoBooster/src/GuiTopBar.cpp index ebab645..ead1e92 100644 --- a/PianoBooster/src/GuiTopBar.cpp +++ b/PianoBooster/src/GuiTopBar.cpp @@ -121,7 +121,7 @@ void GuiTopBar::reloadKeyCombo(bool major) void GuiTopBar::on_keyCombo_activated(int index) { - CStavePos::setKeySignature(index - 6); + CStavePos::setKeySignature(index - 6, 0); m_song->refreshScroll(); } @@ -144,7 +144,7 @@ void GuiTopBar::on_transposeSpin_valueChanged(int value) int newValue = nextKey[(diff + i + arraySize(nextKey)) % arraySize(nextKey) ]; - CStavePos::setKeySignature( newValue ); + CStavePos::setKeySignature( newValue, 0 ); newValue += 6; keyCombo->setCurrentIndex(newValue); diff --git a/PianoBooster/src/MidiEvent.h b/PianoBooster/src/MidiEvent.h index 1824741..3a7d29e 100644 --- a/PianoBooster/src/MidiEvent.h +++ b/PianoBooster/src/MidiEvent.h @@ -53,8 +53,9 @@ #define MIDI_PB_chordSeparator 0x0ff3 // All the notes (note on) between these counts as one chord #define MIDI_PB_tempo 0x0ff4 #define MIDI_PB_timeSignature 0x0ff5 -#define MIDI_PB_collateRawMidiData 0x0ff6 -#define MIDI_PB_outputRawMidiData 0x0ff7 // Raw data is used for used for a SYSTEM_EVENT +#define MIDI_PB_keySignature 0x0ff6 +#define MIDI_PB_collateRawMidiData 0x0ff7 +#define MIDI_PB_outputRawMidiData 0x0ff8 // Raw data is used for used for a SYSTEM_EVENT /*===================================*/ /* */ diff --git a/PianoBooster/src/MidiTrack.cpp b/PianoBooster/src/MidiTrack.cpp index d1347b2..f924fed 100644 --- a/PianoBooster/src/MidiTrack.cpp +++ b/PianoBooster/src/MidiTrack.cpp @@ -30,7 +30,7 @@ #include "MidiTrack.h" #include "Util.h" -#define OPTION_DEBUG_TRACK 0 +#define OPTION_DEBUG_TRACK 1//fixme 0 #if OPTION_DEBUG_TRACK #define ppDEBUG_TRACK(args) ppDebugTrack args #else @@ -199,9 +199,37 @@ void CMidiTrack::readTimeSignatureEvent() b4 = readByte(); /* Ignore the last bytes */ event.metaEvent(readDelaTime(), MIDI_PB_timeSignature, timeSigNumerator, 1<push(event); - ppDEBUG_TRACK((4,"Time Signature %d/%d metronome %d quarter %d", timeSigNumerator, 1<(readByte()); // force sign converstion The key sig 0=middle C + majorKey =readByte(); // Major or Minor + if (keySig >= 7 || keySig <= -7 ) + { + errorFail(SMF_CORRUPTED_MIDI_FILE); + return; + } + + event.metaEvent(readDelaTime(), MIDI_PB_keySignature, keySig, majorKey); + m_trackEventQueue->push(event); + ppDEBUG_TRACK((4,"Key Signature %d maj/min %d", keySig, majorKey)); +} + + void CMidiTrack::readMetaEvent(byte_t type) { @@ -267,11 +295,8 @@ void CMidiTrack::readMetaEvent(byte_t type) break; case METAKEYSIG: /* Key Signature */ - { - data = readDataEvent(2); - ppDEBUG_TRACK((4,"Key Signature %d %s", (int)(data>>8), ((data&0xff) ==0)?"Major":"Minor")); - break; - } + readKeySignatureEvent(); + break; case METATEXT: /* Text Event */ text = readTextEvent(); @@ -313,11 +338,14 @@ void CMidiTrack::readMetaEvent(byte_t type) ppDEBUG_TRACK((2,"MIDI Port %lu", data)); break; + case 0x09: // meta type + text = readTextEvent(); + ppDEBUG_TRACK((2,"fixme midi meta event 0x%02x %s", type, text.c_str())); + break; default: /* Unknown meta type */ text = readTextEvent(); - //strict_error("SM9"); - ppDEBUG_TRACK((99,"UNKNOWN meta event 0x%02x %s", type, text.c_str())); - errorFail(SMF_UNKNOW_EVENT); + ppLogWarn("unknown midi meta event 0x%02x %s", type, text.c_str()); + //errorFail(SMF_UNKNOW_EVENT); break; } } @@ -342,7 +370,6 @@ void CMidiTrack::decodeSystemMessage( byte_t status, byte_t data1 ) default: ppDEBUG_TRACK((99,"UNKNOWN")); ignoreSysexEvent(data1); - //strict_error("SM8"); //read_sysex_event(); errorFail(SMF_UNKNOW_EVENT); break; diff --git a/PianoBooster/src/MidiTrack.h b/PianoBooster/src/MidiTrack.h index 99dd4ef..f984dfe 100644 --- a/PianoBooster/src/MidiTrack.h +++ b/PianoBooster/src/MidiTrack.h @@ -102,7 +102,7 @@ private: { m_midiError = error; if (m_midiError != SMF_NO_ERROR) - ppError("Error Fail %d", m_midiError); + ppError("Midi error %d", m_midiError); } } @@ -152,6 +152,7 @@ private: void ignoreSysexEvent(byte_t data); void readTimeSignatureEvent(); + void readKeySignatureEvent(); void decodeSystemMessage( byte_t status, byte_t data1 ); diff --git a/PianoBooster/src/Notation.cpp b/PianoBooster/src/Notation.cpp index 8669721..de0a6b5 100644 --- a/PianoBooster/src/Notation.cpp +++ b/PianoBooster/src/Notation.cpp @@ -94,7 +94,7 @@ void CSlot::analyse() CSlot CNotation::nextBeatMarker() { - const int cfg_barGap = CMidiFile::getPulsesPerQuarterNote() * 30 / DEFAULT_PPQN; + const int cfg_barGap = CMidiFile::ppqnAdjust(30); CSlot slot; @@ -140,6 +140,31 @@ int CNotation::nextMergeSlot() return nearestIndex; } +accidentalModifer_t CNotation::detectSuppressedNatural(int note) +{ + accidentalModifer_t modifer = PB_ACCIDENTAL_MODIFER_noChange; + + if (note <= 0 || note +1 >= MAX_MIDI_NOTES) + return modifer; + + while (m_earlyBarChangeDelta >= m_bar.getBarLength()) + { + m_earlyBarChangeDelta -= m_bar.getBarLength(); + m_earlyBarChangeCounter++; + } + //int accidental = CStavePos::getStaveAccidental(note); + // check if this note has occured in this bar before + if (m_noteState[note].getBarChange() == m_earlyBarChangeCounter) + modifer = PB_ACCIDENTAL_MODIFER_suppress_accidental; + /* + if (m_noteState[note + 1].getBarChange() == m_earlyBarChangeCounter) + modifer = PB_ACCIDENTAL_MODIFER_above; + if (m_noteState[note - 1].getBarChange() == m_earlyBarChangeCounter) + modifer = PB_ACCIDENTAL_MODIFER_below;*/ + m_noteState[note].setBarChange(m_earlyBarChangeCounter); + return modifer; +} + void CNotation::findNoteSlots() { CMidiEvent midi; @@ -154,6 +179,7 @@ void CNotation::findNoteSlots() midi = m_midiInputQueue->pop(); m_currentDeltaTime += midi.deltaTime(); + m_earlyBarChangeDelta += midi.deltaTime(); if (midi.type() == MIDI_PB_chordSeparator || midi.type() == MIDI_PB_EOF) { if (m_currentSlot.length() > 0) @@ -173,6 +199,8 @@ void CNotation::findNoteSlots() else if (midi.type() == MIDI_PB_timeSignature) m_bar.setTimeSig(midi.data1(), midi.data2()); + else if (midi.type() == MIDI_PB_keySignature) + CStavePos::setKeySignature(midi.data1(), midi.data2()); else if (midi.type() == MIDI_NOTE_ON) { whichPart_t hand = CNote::findHand( midi, m_displayChannel, PB_PART_both ); @@ -185,8 +213,12 @@ void CNotation::findNoteSlots() symbolType = PB_SYMBOL_note; CSymbol symbol(symbolType, hand, midi.note()); symbol.setColour(Cfg::noteColour()); + + // check if this note has occured in this bar before + symbol.setAccidentalModifer(detectSuppressedNatural(midi.note())); + if (m_currentSlot.addSymbol(symbol) == false) { - ppLogWarn("[%d] Over the Max symbols limit", m_displayChannel + 1); //fix me + ppLogWarn("[%d] Over the Max symbols limit", m_displayChannel + 1); //fixme } m_currentSlot.addDeltaTime(m_currentDeltaTime); m_currentDeltaTime = 0; @@ -195,6 +227,7 @@ void CNotation::findNoteSlots() if (midi.note() < MIDI_BOTTOM_C) m_currentSlot.setAv8Left(MIDI_OCTAVE); } + } } } @@ -255,6 +288,8 @@ void CNotation::midiEventInsert(CMidiEvent event) void CNotation::reset() { + const int cfg_earlBarLead = CMidiFile::ppqnAdjust(8); + size_t i; m_currentDeltaTime = 0; m_midiInputQueue->clear(); @@ -263,6 +298,13 @@ void CNotation::reset() m_mergeSlots[i].clear(); m_currentSlot.clear(); m_beatPerBarCounter=0; + m_earlyBarChangeCounter = 0; + m_earlyBarChangeDelta = cfg_earlBarLead; // We want to detect the bar change early + m_bar.reset(); m_findScrollerChord.reset(); + for( i = 0; i < MAX_MIDI_NOTES; i++) + { + m_noteState[i].clear(); + } } diff --git a/PianoBooster/src/Notation.h b/PianoBooster/src/Notation.h index ab5bcd5..a529e2c 100644 --- a/PianoBooster/src/Notation.h +++ b/PianoBooster/src/Notation.h @@ -128,6 +128,31 @@ private: int m_maxLeftEdge; // the furthest the note will appear on the left hand edge (used when removing the note) }; +// remembers the state of a running accidental +// Don't display the accidental twice in the same bar +class CNoteState +{ +public: + CNoteState() + { + clear(); + } + void clear() + { + m_barChangeCounter = 0; + m_accidentalState = PB_ACCIDENTAL_MODIFER_noChange; + m_noteLength = 0; + } + void setBarChange(int value){m_barChangeCounter = value;} + int getBarChange(){return m_barChangeCounter;} + void setAccidentalState(accidentalModifer_t value){m_accidentalState = value;} + accidentalModifer_t setAccidentalState(){return m_accidentalState;} + +private: + int m_barChangeCounter; + accidentalModifer_t m_accidentalState; + int m_noteLength; // Used to determine the note length +}; // Define a chord class CNotation @@ -160,16 +185,21 @@ private: int nextMergeSlot(); void findNoteSlots(); CSlot nextNoteSlot(); + accidentalModifer_t detectSuppressedNatural(int note); + CQueue* m_slotQueue; // Queue of symbol slots that have not been read yet CQueue* m_midiInputQueue; // A Queue of midi events CSlot m_currentSlot; int m_currentDeltaTime; int m_beatPerBarCounter; + int m_earlyBarChangeCounter; + int m_earlyBarChangeDelta; // Counts the ppqn in one bar CSlot m_mergeSlots[2]; int m_displayChannel; CFindChord m_findScrollerChord; CBar m_bar; + CNoteState m_noteState[MAX_MIDI_NOTES]; }; #endif // __NOTATION_H__ diff --git a/PianoBooster/src/Settings.cpp b/PianoBooster/src/Settings.cpp index f3dc7a9..16424d3 100755 --- a/PianoBooster/src/Settings.cpp +++ b/PianoBooster/src/Settings.cpp @@ -311,8 +311,8 @@ void CSettings::setCurrentSongName(const QString & name) m_song->loadSong(getCurrentSongLongFileName()); loadSongSettings(); - m_guiTopBar->refresh(true); m_guiSidePanel->refresh(); + m_guiTopBar->refresh(true); m_mainWindow->setWindowTitle("Piano Booster - " + m_song->getSongTitle()); } diff --git a/PianoBooster/src/Song.cpp b/PianoBooster/src/Song.cpp index f4d6441..cee5f4c 100644 --- a/PianoBooster/src/Song.cpp +++ b/PianoBooster/src/Song.cpp @@ -58,12 +58,13 @@ void CSong::loadSong(const QString & filename) if (index >= 0) m_songTitle = m_songTitle.right( m_songTitle.length() - index - 1); + QString fn = filename; #ifdef _WIN32 - filename = filename.replace('/','\\'); + fn = fn.replace('/','\\'); #endif m_midiFile->setLogLevel(3); - m_midiFile->openMidiFile(string(filename.toAscii())); - ppLogInfo("Opening song %s", string(filename.toAscii()).c_str()); + m_midiFile->openMidiFile(string(fn.toAscii())); + ppLogInfo("Opening song %s", string(fn.toAscii()).c_str()); transpose(0); midiFileInfo(); m_midiFile->setLogLevel(99); @@ -83,6 +84,7 @@ void CSong::midiFileInfo() { m_trackList->clear(); setTimeSig(0,0); + CStavePos::setKeySignature( NOT_USED, 0 ); // Read the next events to find the active channels CMidiEvent event; diff --git a/PianoBooster/src/Song.h b/PianoBooster/src/Song.h index 26ceb3f..6aeabce 100644 --- a/PianoBooster/src/Song.h +++ b/PianoBooster/src/Song.h @@ -43,7 +43,7 @@ class CSong : public CConductor public: CSong() { - CStavePos::setKeySignature(0); + CStavePos::setKeySignature( NOT_USED, 0 ); m_midiFile = new CMidiFile; m_trackList = new CTrackList; diff --git a/PianoBooster/src/StavePosition.cpp b/PianoBooster/src/StavePosition.cpp index da329d6..7477966 100644 --- a/PianoBooster/src/StavePosition.cpp +++ b/PianoBooster/src/StavePosition.cpp @@ -32,6 +32,7 @@ float CStavePos::m_staveCenterY; int CStavePos::m_KeySignature; +int CStavePos::m_KeySignatureMajorMinor; const staveLookup_t* CStavePos::m_staveLookUpTable; float CStavePos::m_staveCentralOffset = (staveHeight() * 3)/2; @@ -84,9 +85,12 @@ staveLookup_t CStavePos::midiNote2Name(int midiNote) return item; } -void CStavePos::setKeySignature(int key) +void CStavePos::setKeySignature(int key, int majorMinor) { m_KeySignature = key; + m_KeySignatureMajorMinor = majorMinor; + if (key == NOT_USED) + key = 0; m_staveLookUpTable = getstaveLookupTable(key); CDraw::forceCompileRedraw(); } diff --git a/PianoBooster/src/StavePosition.h b/PianoBooster/src/StavePosition.h index 161860b..68e6f27 100644 --- a/PianoBooster/src/StavePosition.h +++ b/PianoBooster/src/StavePosition.h @@ -113,7 +113,7 @@ public: static float getVerticalNoteSpacing(){return verticalNoteSpacing();} static float getStaveCenterY(){return m_staveCenterY;} static void setStaveCenterY(float y) { m_staveCenterY = y; } - static void setKeySignature(int key); + static void setKeySignature(int key, int majorMinor); static int getKeySignature() {return m_KeySignature;} static void setStaveCentralOffset(float gap) { m_staveCentralOffset = gap; } static float verticalNoteSpacing() {return 7;} @@ -122,6 +122,13 @@ public: // convert the midi note to the note name A B C D E F G static staveLookup_t midiNote2Name(int midiNote); static const staveLookup_t* getstaveLookupTable(int key); + + // do we show a sharp or a flat for this key signature + static int getStaveAccidental(int midiNote) + { + return m_staveLookUpTable[midiNote%12].accidental; + } + private: // fixme TODO This could be improved as the calculations could a done in the constructor @@ -132,6 +139,7 @@ private: static int m_KeySignature; + static int m_KeySignatureMajorMinor; static const staveLookup_t* m_staveLookUpTable; static float m_staveCentralOffset; static float m_staveCenterY; diff --git a/PianoBooster/src/Symbol.h b/PianoBooster/src/Symbol.h index 8256330..6046e14 100644 --- a/PianoBooster/src/Symbol.h +++ b/PianoBooster/src/Symbol.h @@ -52,6 +52,13 @@ typedef enum PB_SYMBOL_theEnd } musicalSymbol_t; + +typedef enum { + PB_ACCIDENTAL_MODIFER_noChange, + PB_ACCIDENTAL_MODIFER_suppress_accidental, + PB_ACCIDENTAL_MODIFER_force_natural +} accidentalModifer_t; + #define BEAT_MARKER_OFFSET 20 // used to ensure that beat markers are drawn under the note by drawing them early class CSymbol @@ -125,6 +132,16 @@ public: int getNoteIndex() { return m_index; } int getNoteTotal() { return m_total; } + //////////////////////////////////////////////////////////////////////////////// + //! @brief The accidental + //! return 0 = none, 1=sharp, -1 =flat, 2=natural. + int getAccidental() { + return getStavePos().getAccidental(); + } + + + void setAccidentalModifer(accidentalModifer_t value) {m_accidentalModifer = value;} + accidentalModifer_t getAccidentalModifer() {return m_accidentalModifer;} private: @@ -136,11 +153,13 @@ private: m_midiDuration = 0; m_pianistTiming = NOT_USED; setIndex(0,0); + m_accidentalModifer = PB_ACCIDENTAL_MODIFER_noChange; } CStavePos m_stavePos; musicalSymbol_t m_symbolType; byte m_midiNote; + accidentalModifer_t m_accidentalModifer; // Used to suppress the second sharp in the same bar unsigned long m_midiDuration; whichPart_t m_hand; diff --git a/PianoBooster/src/TrackList.cpp b/PianoBooster/src/TrackList.cpp index 5793f96..75a7d9e 100644 --- a/PianoBooster/src/TrackList.cpp +++ b/PianoBooster/src/TrackList.cpp @@ -202,7 +202,8 @@ void CTrackList::refresh() } } - CStavePos::setKeySignature(guessKeySignature(CNote::rightHandChan(),CNote::leftHandChan())); + if (CStavePos::getKeySignature() == NOT_USED) + CStavePos::setKeySignature(guessKeySignature(CNote::rightHandChan(),CNote::leftHandChan()), 0); int goodChan = -1; // Find an unused channel that we can use for the keyboard