예제 #1
0
파일: PsamContolLib.cs 프로젝트: mowie2/DPA
        private void DoNote()
        {
            DomainModel.Note cr = (DomainModel.Note)currentNote;

            if (cr.Pitch == "")
            {
                Rest r = new Rest(durriation[cr.Duration]);
                r.NumberOfDots = cr.Dotted;
                symbols.Add(r);
                return;
            }

            PSAMControlLibrary.Note n = new PSAMControlLibrary.Note(cr.Pitch.ToUpper(), semitones[cr.Semitone], 2 + cr.Octave, durriation[cr.Duration],
                                                                    NoteStemDirection.Up, NoteTieType.None,
                                                                    new List <NoteBeamType>()
            {
                NoteBeamType.Single
            });
            n.NumberOfDots = cr.Dotted;

            float count = 1 / cr.Duration;
            float dur   = (float)((Math.Pow(2, cr.Dotted) - 1) / Math.Pow(2, cr.Dotted)) + 1;

            barlinecount += (count * dur);
            symbols.Add(n);
        }
예제 #2
0
        private void AddNote(Note note)
        {
            // set modifier; negative for flats, positive for sharp
            int modifier = 0;

            if (note.Modifier == Modifiers.Flat)
            {
                modifier = -1;
            }
            else if (note.Modifier == Modifiers.Sharp)
            {
                modifier = 1;
            }

            // set stem direction
            var direction = GetStemDirection(note);

            var amount = AmountOfBeams(note.Duration);

            if (amount > 0)
            {
                _buffer.Add(new NoteBeams
                {
                    Note  = note,
                    Beams = Enumerable.Repeat(NoteBeamType.Single, amount).ToList()
                });

                if (_buffer.Count > 3)
                {
                    FlushBuffer();
                }
                return; // don't add anything till buffer is full or flushed
            }

            // if buffer has items, flush before adding new notes
            if (_buffer.Count > 0)
            {
                FlushBuffer();
            }

            var psamNote = new PSAMNote(note.Name.ToString(), modifier, (int)note.Octave,
                                        (MusicalSymbolDuration)note.Duration, direction, NoteTieType.None, new List <NoteBeamType> {
                NoteBeamType.Single
            });

            // set dots
            psamNote.NumberOfDots = note.Dots;

            _notes.Add(psamNote);
        }
예제 #3
0
        public override void AddSymbol(INote note)
        {
            int octave = note.Pitch / 12 - 1;

            Note staffNote = new Note(note.NoteName.ToString().ToUpper(),
                                      note.NoteAlteration, octave, (MusicalSymbolDuration)note.Duration, NoteStemDirection.Up,
                                      (NoteTieType)note.NoteTieType, new List <NoteBeamType>()
            {
                NoteBeamType.Single
            });

            staffNote.NumberOfDots = note.Dots;

            Symbols.Add(staffNote);
        }
예제 #4
0
        public static void getMusicSymbols(Staff staff, List <MusicalSymbol> WPFStaffs)
        {
            Clef clef = new Clef(ClefType.GClef, 2);

            if (staff.GetClef() == "bass")
            {
                clef = new Clef(ClefType.CClef, 4);
            }
            WPFStaffs.Add(clef);
            int[] time = staff.GetTime();
            WPFStaffs.Add(new TimeSignature(TimeSignatureType.Numbers, (UInt32)time[0], (UInt32)time[1]));
            List <Bar> bars = staff.GetBars();

            foreach (Bar bar in bars)
            {
                List <NoteRest> notes = bar.GetNotes();
                foreach (NoteRest note in notes)
                {
                    string pitch  = "";
                    int    octave = 0;
                    int    length = 0;
                    int    dots   = 0;
                    note.GetInfo(ref pitch, ref octave, ref length, ref dots);
                    if (pitch.Equals("r"))
                    {
                        var rest = new PSAMControlLibrary.Rest((MusicalSymbolDuration)length);
                        WPFStaffs.Add(rest);
                    }
                    else
                    {
                        int alter = 0;
                        alter += Regex.Matches(pitch, "is").Count;
                        alter -= Regex.Matches(pitch, "es|as").Count;
                        var WPFNote = new PSAMControlLibrary.Note(pitch[0].ToString().ToUpper(), alter, octave,
                                                                  (MusicalSymbolDuration)length, NoteStemDirection.Up, NoteTieType.None,
                                                                  new List <NoteBeamType>()
                        {
                            NoteBeamType.Single
                        })
                        {
                            NumberOfDots = dots
                        };
                        WPFStaffs.Add(WPFNote);
                    }
                }
                WPFStaffs.Add(new Barline());
            }
        }
예제 #5
0
파일: PsamContolLib.cs 프로젝트: mowie2/DPA
        public void DoRepeat()
        {
            DomainModel.BarLine br = (DomainModel.BarLine)currentNote;

            Barline b = new Barline();


            if (br.Type == BarLine.TYPE.REPEAT)
            {
                int     alt      = 1;
                Barline startAlt = new Barline();
                startAlt.AlternateRepeatGroup = alt;
                symbols.Add(startAlt);

                for (int i = 0; i < br.Alternatives.Count; i++)
                {
                    Symbol temp = br.Alternatives[i];
                    while (temp != null)
                    {
                        DomainModel.Note        cr = (DomainModel.Note)temp;
                        PSAMControlLibrary.Note n  = new PSAMControlLibrary.Note(cr.Pitch.ToUpper(), 0, 2 + cr.Octave, durriation[cr.Duration],
                                                                                 NoteStemDirection.Up, NoteTieType.None,
                                                                                 new List <NoteBeamType>()
                        {
                            NoteBeamType.Single
                        });
                        symbols.Add(n);
                        temp = temp.nextSymbol;
                    }

                    if (i == 0)
                    {
                        alt++;
                        Barline blt = new Barline();
                        blt.RepeatSign           = RepeatSignType.Backward;
                        blt.AlternateRepeatGroup = alt;
                        symbols.Add(blt);

                        continue;
                    }
                }
                return;
            }
            b.RepeatSign = reapeatType[br.Type];
            symbols.Add(b);
            barlinecount = 0;
        }
예제 #6
0
        private void HandleNote()
        {
            var note = (Models.Note)_element;

            // Octave
            if (_mustAlterOctave)
            {
                _previousOctave  = _alterOctave;
                _mustAlterOctave = false;
            }
            else
            {
                CalculateOctave(note);
            }

            _previousNote = note.NoteType;

            // Note tie type
            var noteTieType = NoteTieType.None;

            if (note.IsTied)
            {
                noteTieType = NoteTieType.Start;
                _isTied     = true;
            }
            else if (_isTied)
            {
                noteTieType = NoteTieType.Stop;
                _isTied     = false;
            }

            // Create and add new note
            var newNote = new PSAMControlLibrary.Note(note.NoteType.ToString(),
                                                      (int)note.AlterType, _previousOctave, (MusicalSymbolDuration)note.DurationType,
                                                      NoteStemDirection.Up,
                                                      noteTieType, new List <NoteBeamType> {
                NoteBeamType.Single
            })
            {
                NumberOfDots = note.Dots
            };

            _symbols.Add(newNote);
        }
예제 #7
0
        private void AddBeamedNotes(List <NoteBeams> noteBeams)
        {
            // set same directions
            var direction = noteBeams.Select(note => GetStemDirection(note.Note)).Max(d => d);

            // last note to end
            var last = noteBeams[noteBeams.Count - 1];

            for (var i = 0; i < last.Beams.Count; i++)
            {
                if (last.Beams[i] == NoteBeamType.Continue)
                {
                    last.Beams[i] = NoteBeamType.End;
                }
            }

            foreach (var note in noteBeams)
            {
                // set modifier; negative for flats, positive for sharp
                int modifier = 0;
                if (note.Note.Modifier == Modifiers.Flat)
                {
                    modifier = -1;
                }
                else if (note.Note.Modifier == Modifiers.Sharp)
                {
                    modifier = 1;
                }

                var psamNote = new PSAMNote(note.Note.Name.ToString(), modifier, (int)note.Note.Octave,
                                            (MusicalSymbolDuration)note.Note.Duration, direction, NoteTieType.None, note.Beams);

                // set dots
                psamNote.NumberOfDots = note.Note.Dots;

                _notes.Add(psamNote);
            }
        }
예제 #8
0
        /// <summary>
        /// We create MIDI from WPF staffs, 2 different dependencies, not a good practice.
        /// TODO: Create MIDI from our own domain classes.
        /// TODO: Our code doesn't support repeats (rendering notes multiple times) in midi yet. Maybe with a COMPOSITE this will be easier?
        /// </summary>
        /// <returns></returns>
        private Sequence GetSequenceFromWPFStaffs()
        {
            List <string> notesOrderWithCrosses = new List <string>()
            {
                "c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "b"
            };
            int absoluteTicks = 0;

            Sequence sequence = new Sequence();

            Track metaTrack = new Track();

            sequence.Add(metaTrack);

            // Calculate tempo
            int speed = (60000000 / _bpm);

            byte[] tempo = new byte[3];
            tempo[0] = (byte)((speed >> 16) & 0xff);
            tempo[1] = (byte)((speed >> 8) & 0xff);
            tempo[2] = (byte)(speed & 0xff);
            metaTrack.Insert(0 /* Insert at 0 ticks*/, new MetaMessage(MetaType.Tempo, tempo));

            Track notesTrack = new Track();

            sequence.Add(notesTrack);

            for (int i = 0; i < WPFStaffs.Count; i++)
            {
                var musicalSymbol = WPFStaffs[i];
                switch (musicalSymbol.Type)
                {
                case MusicalSymbolType.Note:
                    Note note = musicalSymbol as Note;

                    // Calculate duration
                    double absoluteLength = 1.0 / (double)note.Duration;
                    absoluteLength += (absoluteLength / 2.0) * note.NumberOfDots;

                    double relationToQuartNote  = _beatNote / 4.0;
                    double percentageOfBeatNote = (1.0 / _beatNote) / absoluteLength;
                    double deltaTicks           = (sequence.Division / relationToQuartNote) / percentageOfBeatNote;

                    // Calculate height
                    int noteHeight = notesOrderWithCrosses.IndexOf(note.Step.ToLower()) + ((note.Octave + 1) * 12);
                    noteHeight += note.Alter;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 90));     // Data2 = volume

                    absoluteTicks += (int)deltaTicks;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 0));     // Data2 = volume

                    break;

                case MusicalSymbolType.TimeSignature:
                    byte[] timeSignature = new byte[4];
                    timeSignature[0] = (byte)_beatsPerBar;
                    timeSignature[1] = (byte)(Math.Log(_beatNote) / Math.Log(2));
                    metaTrack.Insert(absoluteTicks, new MetaMessage(MetaType.TimeSignature, timeSignature));
                    break;

                default:
                    break;
                }
            }

            notesTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            metaTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            return(sequence);
        }
예제 #9
0
        private static IEnumerable <MusicalSymbol> GetStaffsFromTokens(LinkedList <LilypondToken> tokens)
        {
            List <MusicalSymbol> symbols = new List <MusicalSymbol>();

            PSAMControlLibrary.Clef currentClef = null;
            int  previousOctave          = 4;
            char previousNote            = 'c';
            bool inRepeat                = false;
            bool inAlternative           = false;
            int  alternativeRepeatNumber = 0;

            LilypondToken currentToken = tokens.First();

            while (currentToken != null)
            {
                // TODO: There are a lot of switches based on LilypondTokenKind, can't those be eliminated en delegated?
                // HINT: Command, Decorator, Factory etc.

                // TODO: Repeats are somewhat weirdly done. Can we replace this with the COMPOSITE pattern?
                switch (currentToken.TokenKind)
                {
                case LilypondTokenKind.Unknown:
                    break;

                case LilypondTokenKind.Repeat:
                    inRepeat = true;
                    symbols.Add(new Barline()
                    {
                        RepeatSign = RepeatSignType.Forward
                    });
                    break;

                case LilypondTokenKind.SectionEnd:
                    if (inRepeat && currentToken.NextToken?.TokenKind != LilypondTokenKind.Alternative)
                    {
                        inRepeat = false;
                        symbols.Add(new Barline()
                        {
                            RepeatSign = RepeatSignType.Backward, AlternateRepeatGroup = alternativeRepeatNumber
                        });
                    }
                    else if (inAlternative && alternativeRepeatNumber == 1)
                    {
                        alternativeRepeatNumber++;
                        symbols.Add(new Barline()
                        {
                            RepeatSign = RepeatSignType.Backward, AlternateRepeatGroup = alternativeRepeatNumber
                        });
                    }
                    else if (inAlternative && currentToken.NextToken.TokenKind == LilypondTokenKind.SectionEnd)
                    {
                        inAlternative           = false;
                        alternativeRepeatNumber = 0;
                    }
                    break;

                case LilypondTokenKind.SectionStart:
                    if (inAlternative && currentToken.PreviousToken.TokenKind != LilypondTokenKind.SectionEnd)
                    {
                        alternativeRepeatNumber++;
                        symbols.Add(new Barline()
                        {
                            AlternateRepeatGroup = alternativeRepeatNumber
                        });
                    }
                    break;

                case LilypondTokenKind.Alternative:
                    inAlternative = true;
                    inRepeat      = false;
                    currentToken  = currentToken.NextToken;    // Skip the first bracket open.
                    break;

                case LilypondTokenKind.Note:
                    // Tied
                    // TODO: A tie, like a dot and cross or mole are decorations on notes. Is the DECORATOR pattern of use here?
                    NoteTieType tie = NoteTieType.None;
                    if (currentToken.Value.StartsWith("~"))
                    {
                        tie = NoteTieType.Stop;
                        var lastNote = symbols.Last(s => s is PSAMControlLibrary.Note) as PSAMControlLibrary.Note;
                        if (lastNote != null)
                        {
                            lastNote.TieType = NoteTieType.Start;
                        }
                        currentToken.Value = currentToken.Value.Substring(1);
                    }
                    // Length
                    int noteLength = Int32.Parse(Regex.Match(currentToken.Value, @"\d+").Value);
                    // Crosses and Moles
                    int alter = 0;
                    alter += Regex.Matches(currentToken.Value, "is").Count;
                    alter -= Regex.Matches(currentToken.Value, "es|as").Count;
                    // Octaves
                    int distanceWithPreviousNote = notesorder.IndexOf(currentToken.Value[0]) - notesorder.IndexOf(previousNote);
                    if (distanceWithPreviousNote > 3)     // Shorter path possible the other way around
                    {
                        distanceWithPreviousNote -= 7;    // The number of notes in an octave
                    }
                    else if (distanceWithPreviousNote < -3)
                    {
                        distanceWithPreviousNote += 7;     // The number of notes in an octave
                    }

                    if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) >= 7)
                    {
                        previousOctave++;
                    }
                    else if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) < 0)
                    {
                        previousOctave--;
                    }

                    // Force up or down.
                    previousOctave += currentToken.Value.Count(c => c == '\'');
                    previousOctave -= currentToken.Value.Count(c => c == ',');

                    previousNote = currentToken.Value[0];

                    var note = new PSAMControlLibrary.Note(currentToken.Value[0].ToString().ToUpper(), alter, previousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, tie, new List <NoteBeamType>()
                    {
                        NoteBeamType.Single
                    });
                    note.NumberOfDots += currentToken.Value.Count(c => c.Equals('.'));

                    symbols.Add(note);
                    break;

                case LilypondTokenKind.Rest:
                    var restLength = Int32.Parse(currentToken.Value[1].ToString());
                    symbols.Add(new PSAMControlLibrary.Rest((MusicalSymbolDuration)restLength));
                    break;

                case LilypondTokenKind.Bar:
                    symbols.Add(new Barline()
                    {
                        AlternateRepeatGroup = alternativeRepeatNumber
                    });
                    break;

                case LilypondTokenKind.Clef:
                    currentToken = currentToken.NextToken;
                    if (currentToken.Value == "treble")
                    {
                        currentClef = new PSAMControlLibrary.Clef(ClefType.GClef, 2);
                    }
                    else if (currentToken.Value == "bass")
                    {
                        currentClef = new PSAMControlLibrary.Clef(ClefType.FClef, 4);
                    }
                    else
                    {
                        throw new NotSupportedException($"Clef {currentToken.Value} is not supported.");
                    }

                    symbols.Add(currentClef);
                    break;

                case LilypondTokenKind.Time:
                    currentToken = currentToken.NextToken;
                    var times = currentToken.Value.Split('/');
                    symbols.Add(new TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1])));
                    break;

                case LilypondTokenKind.Tempo:
                    // Tempo not supported
                    break;

                default:
                    break;
                }
                currentToken = currentToken.NextToken;
            }

            return(symbols);
        }
예제 #10
0
        private static IEnumerable <MusicalSymbol> GetStaffsFromTokens(LinkedList <LilypondToken> tokens, out string message)
        {
            List <MusicalSymbol> symbols = new List <MusicalSymbol>();

            message = "";

            try
            {
                Clef currentClef    = null;
                int  previousOctave = 4;
                char previousNote   = 'c';

                LilypondToken currentToken = tokens.First();
                while (currentToken != null)
                {
                    switch (currentToken.TokenKind)
                    {
                    case LilypondTokenKind.Unknown:
                        break;

                    case LilypondTokenKind.Note:
                        // Length
                        int noteLength = Int32.Parse(Regex.Match(currentToken.Value, @"\d+").Value);
                        // Crosses and Moles
                        int alter = 0;
                        alter += Regex.Matches(currentToken.Value, "is").Count;
                        alter -= Regex.Matches(currentToken.Value, "es|as").Count;
                        // Octaves
                        int distanceWithPreviousNote = notesorder.IndexOf(currentToken.Value[0]) - notesorder.IndexOf(previousNote);
                        if (distanceWithPreviousNote > 3)     // Shorter path possible the other way around
                        {
                            distanceWithPreviousNote -= 7;    // The number of notes in an octave
                        }
                        else if (distanceWithPreviousNote < -3)
                        {
                            distanceWithPreviousNote += 7;     // The number of notes in an octave
                        }

                        if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) >= 7)
                        {
                            previousOctave++;
                        }
                        else if (distanceWithPreviousNote + notesorder.IndexOf(previousNote) < 0)
                        {
                            previousOctave--;
                        }

                        // Force up or down.
                        previousOctave += currentToken.Value.Count(c => c == '\'');
                        previousOctave -= currentToken.Value.Count(c => c == ',');

                        previousNote = currentToken.Value[0];

                        var note = new PSAMControlLibrary.Note(currentToken.Value[0].ToString().ToUpper(), alter, previousOctave, (MusicalSymbolDuration)noteLength, NoteStemDirection.Up, NoteTieType.None, new List <NoteBeamType>()
                        {
                            NoteBeamType.Single
                        });
                        note.NumberOfDots += currentToken.Value.Count(c => c.Equals('.'));

                        symbols.Add(note);
                        break;

                    case LilypondTokenKind.Rest:
                        var restLength = Int32.Parse(currentToken.Value[1].ToString());
                        symbols.Add(new Rest((MusicalSymbolDuration)restLength));
                        break;

                    case LilypondTokenKind.Bar:
                        symbols.Add(new Barline());
                        break;

                    case LilypondTokenKind.Clef:
                        currentToken = currentToken.NextToken;
                        if (currentToken.Value == "treble")
                        {
                            currentClef = new Clef(ClefType.GClef, 2);
                        }
                        else if (currentToken.Value == "bass")
                        {
                            currentClef = new Clef(ClefType.FClef, 4);
                        }
                        else
                        {
                            throw new NotSupportedException($"Clef {currentToken.Value} is not supported.");
                        }

                        symbols.Add(currentClef);
                        break;

                    case LilypondTokenKind.Time:
                        currentToken = currentToken.NextToken;
                        var times = currentToken.Value.Split('/');
                        symbols.Add(new TimeSignature(TimeSignatureType.Numbers, UInt32.Parse(times[0]), UInt32.Parse(times[1])));
                        break;

                    case LilypondTokenKind.Tempo:
                        // Tempo not supported
                        break;

                    default:
                        break;
                    }
                    currentToken = currentToken.NextToken;
                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }

            return(symbols);
        }
예제 #11
0
        public Sequence GetSequenceFromStaff(Staff staff)
        {
            List <string> notesOrderWithCrosses = new List <string>()
            {
                "c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "b"
            };
            int      absoluteTicks = 0;
            Sequence sequence      = new Sequence();
            Track    metaTrack     = new Track();

            sequence.Add(metaTrack);
            Track notesTrack = new Track();

            sequence.Add(notesTrack);

            int speed = 60000000 / staff.GetTempo();

            byte[] tempo = new byte[3];
            tempo[0] = (byte)((speed >> 16) & 0xff);
            tempo[1] = (byte)((speed >> 8) & 0xff);
            tempo[2] = (byte)(speed & 0xff);
            metaTrack.Insert(0 /* Insert at 0 ticks*/, new MetaMessage(MetaType.Tempo, tempo));

            List <MusicalSymbol> WPFStaffs = new List <MusicalSymbol>();

            WPFManager.getMusicSymbols(staff, WPFStaffs);
            foreach (MusicalSymbol musicalSymbol in WPFStaffs)
            {
                int[]  time;
                double absoluteLength;
                double relationToQuartNote;
                double percentageOfBeatNote;
                double deltaTicks;
                switch (musicalSymbol.Type)
                {
                case MusicalSymbolType.Note:
                    Note note = musicalSymbol as Note;

                    absoluteLength  = 1.0 / (double)note.Duration;
                    absoluteLength += (absoluteLength / 2.0) * note.NumberOfDots;

                    time = staff.GetTime();
                    relationToQuartNote  = time[1] / 4.0;
                    percentageOfBeatNote = (1.0 / time[1]) / absoluteLength;
                    deltaTicks           = (sequence.Division / relationToQuartNote) / percentageOfBeatNote;

                    // Calculate height
                    int noteHeight = notesOrderWithCrosses.IndexOf(note.Step.ToLower()) + ((note.Octave + 1) * 12);
                    noteHeight += note.Alter;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 90));     // Data2 = volume

                    absoluteTicks += (int)deltaTicks;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 0));     // Data2 = volume
                    break;

                case MusicalSymbolType.Rest:
                    Rest rest = musicalSymbol as Rest;

                    absoluteLength  = 1.0 / (double)rest.Duration;
                    absoluteLength += (absoluteLength / 2.0) * rest.NumberOfDots;

                    time = staff.GetTime();
                    relationToQuartNote  = time[1] / 4.0;
                    percentageOfBeatNote = (1.0 / time[1]) / absoluteLength;
                    deltaTicks           = (sequence.Division / relationToQuartNote) / percentageOfBeatNote;
                    absoluteTicks       += (int)deltaTicks;
                    break;

                case MusicalSymbolType.TimeSignature:
                    time = staff.GetTime();
                    byte[] timeSignature = new byte[4];
                    timeSignature[0] = (byte)time[0];
                    timeSignature[1] = (byte)(Math.Log(time[1]) / Math.Log(2));
                    metaTrack.Insert(absoluteTicks, new MetaMessage(MetaType.TimeSignature, timeSignature));
                    break;

                default:
                    break;
                }
            }
            notesTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            metaTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            return(sequence);
        }