import { IXmlElement , IXmlAttribute } from "../../../Common/FileIO/Xml" ; import { MusicSheet } from "../../MusicSheet" ; import { ChordDegreeText , ChordSymbolContainer , ChordSymbolEnum , Degree } from "../../VoiceData/ChordSymbolContainer" ; import { AccidentalEnum , NoteEnum , Pitch } from "../../../Common/DataObjects/Pitch" ; import { KeyInstruction } from "../../VoiceData/Instructions/KeyInstruction" ; import { ITextTranslation } from "../../Interfaces/ITextTranslation" ; import log from "loglevel" ; export class ChordSymbolReader { public static readChordSymbol ( xmlNode , musicSheet , activeKey ) { const root = xmlNode . element ( "root" ) ; const kind = xmlNode . element ( "kind" ) ; const kindText = kind . attribute ( "text" ) ; if ( ! root || ! kind ) { return undefined ; } const rootStep = root . element ( "root-step" ) ; const rootAlter = root . element ( "root-alter" ) ; if ( ! rootStep ) { return undefined ; } let rootNote ; try { rootNote = NoteEnum [ rootStep . value . trim ( ) ] ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; return undefined ; } let rootAlteration = AccidentalEnum . NONE ; if ( rootAlter ) { try { rootAlteration = Pitch . AccidentalFromHalfTones ( parseInt ( rootAlter . value , 10 ) ) ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; } } const rootPitch = new Pitch ( rootNote , 1 , rootAlteration ) ; let kindValue = kind . value . trim ( ) . replace ( "-" , "" ) ; if ( kindText ) { switch ( kindText . value ) { case "aug" : kindValue = "augmented" ; break ; case "dim" : kindValue = "diminished" ; break ; default : } } let chordKind ; try { chordKind = ChordSymbolEnum [ kindValue ] ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; return undefined ; } let bassPitch = undefined ; const bass = xmlNode . element ( "bass" ) ; if ( bass ) { const bassStep = bass . element ( "bass-step" ) ; const bassAlter = bass . element ( "bass-alter" ) ; let bassNote = NoteEnum . C ; if ( bassStep ) { try { bassNote = NoteEnum [ bassStep . value . trim ( ) ] ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; return undefined ; } } let bassAlteration = AccidentalEnum . NONE ; if ( bassAlter ) { try { bassAlteration = Pitch . AccidentalFromHalfTones ( parseInt ( bassAlter . value , 10 ) ) ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; } } bassPitch = new Pitch ( bassNote , 1 , bassAlteration ) ; } const degrees = [ ] ; const degreeNodes = xmlNode . elements ( "degree" ) ; for ( const degreeNode of degreeNodes ) { if ( degreeNode ) { const degreeValue = degreeNode . element ( "degree-value" ) ; const degreeAlter = degreeNode . element ( "degree-alter" ) ; const degreeType = degreeNode . element ( "degree-type" ) ; if ( ! degreeValue || ! degreeAlter || ! degreeType ) { return undefined ; } let value ; try { value = parseInt ( degreeValue . value . trim ( ) , 10 ) ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; return undefined ; } let alter ; try { alter = Pitch . AccidentalFromHalfTones ( parseInt ( degreeAlter . value , 10 ) ) ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; return undefined ; } let text ; try { text = ChordDegreeText [ degreeType . value . trim ( ) . toLowerCase ( ) ] ; } catch ( ex ) { const errorMsg = ITextTranslation . translateText ( "ReaderErrorMessages/ChordSymbolError" , "Invalid chord symbol" ) ; musicSheet . SheetErrors . pushMeasureError ( errorMsg ) ; log . debug ( "InstrumentReader.readChordSymbol" , errorMsg , ex ) ; return undefined ; } degrees . push ( new Degree ( value , alter , text ) ) ; } } return new ChordSymbolContainer ( rootPitch , chordKind , bassPitch , degrees , musicSheet . Rules ) ; } }