MusicBoxConverter/MusicBoxConverter/MusicBoxScoreGenerator.cs

98 lines
2.7 KiB
C#
Raw Normal View History

using System;
2017-11-30 23:03:55 +00:00
using System.Collections.Generic;
using System.Linq;
using Melanchall.DryWetMidi.Smf;
using Melanchall.DryWetMidi.Smf.Interaction;
2017-11-30 23:03:55 +00:00
using SBRL.Utilities;
namespace MusicBoxConverter
{
2017-12-02 19:47:40 +00:00
public class MusicBoxScoreGenerator
{
public Vector2 offset { get; set; } = new Vector2(10, 10);
public Vector2 scaleFactor { get; set; } = new Vector2(0.1f, 4f);
public int holeSize { get; set; } = 5;
2017-12-02 19:47:40 +00:00
private int trackLength;
public int TrackLength
{
get
{
if (trackLength == 0)
trackLength = (int)AllNotes().Max((Note arg) => arg.Time);
return trackLength;
}
}
public int MaxNoteNumber {
get {
// TODO: Update to get the max note number supported by the music box
return AllNotes().Max((Note note) => note.NoteNumber);
}
}
public int MinNoteNumber {
get
{
// TODO: Update to get the min note number supported by the music box
return AllNotes().Min((Note note) => note.NoteNumber);
}
}
2017-12-02 19:47:40 +00:00
public MusicBox MusicBox { get; private set; }
MidiFile midiFile;
2017-12-02 19:47:40 +00:00
public MusicBoxScoreGenerator(string filename, MusicBox inMusicBox)
{
2017-12-02 19:47:40 +00:00
MusicBox = inMusicBox;
midiFile = MidiFile.Read("/home/sbrl/Music/Sheets/HappyBirthday.midi");
2017-12-02 19:47:40 +00:00
foreach(Note note in AllNotes()) {
if (!MusicBox.IsValidNote(note))
Console.Error.WriteLine($"Warning: The note {note} at {note.Time} can't be played by the {MusicBox}.");
2017-12-02 19:47:40 +00:00
}
}
public void Output(string destinationFilename)
{
Vector2 area = new Vector2(TrackLength, MaxNoteNumber - MinNoteNumber).Multiply(scaleFactor);
2017-12-02 16:44:12 +00:00
Vector2 size = area.Add(offset.Multiply(2));
SvgWriter svg = new SvgWriter(destinationFilename, size.X.ToString(), size.Y.ToString());
for(int i = 0; i < area.Y; i += 5)
2017-12-02 14:38:49 +00:00
{
2017-12-02 16:44:12 +00:00
Vector2 start = offset.Add(new Vector2(0, i * scaleFactor.Y));
svg.WriteLine(start, start.Add(new Vector2(TrackLength * scaleFactor.X, 0)));
2017-12-02 14:38:49 +00:00
}
2017-12-02 16:44:12 +00:00
svg.WriteRectangle(offset, area);
2017-11-30 23:03:55 +00:00
foreach(Note note in AllNotes())
{
Console.WriteLine("[{0}] {1}{2}/{3}", note.Time, note.NoteName, note.Octave, note.NoteNumber);
2017-11-30 23:03:55 +00:00
svg.WriteCircle(
new Vector2(
offset.X + note.Time * scaleFactor.X,
offset.Y + note.NoteNumber * scaleFactor.Y
),
holeSize // radius
);
}
svg.Complete();
}
public IEnumerable<Note> AllNotes()
{
foreach(TrackChunk chunk in midiFile.Chunks.OfType<TrackChunk>())
{
using(NotesManager notesManager = new NotesManager(chunk.Events))
{
foreach(Note note in notesManager.Notes)
2017-11-30 23:03:55 +00:00
yield return note;
}
}
}
}
}