2017-11-30 22:45:39 +00:00
|
|
|
|
using System;
|
2017-11-30 23:03:55 +00:00
|
|
|
|
using System.Collections.Generic;
|
2017-11-30 22:45:39 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using Melanchall.DryWetMidi.Smf;
|
|
|
|
|
using Melanchall.DryWetMidi.Smf.Interaction;
|
|
|
|
|
|
2017-11-30 23:03:55 +00:00
|
|
|
|
using SBRL.Utilities;
|
|
|
|
|
|
2017-11-30 22:45:39 +00:00
|
|
|
|
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);
|
|
|
|
|
|
2017-12-03 13:51:57 +00:00
|
|
|
|
public int holeSize { get; set; } = 3;
|
2017-11-30 22:45:39 +00:00
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-02 20:47:40 +00:00
|
|
|
|
public int MaxNoteNumber {
|
|
|
|
|
get {
|
2017-12-03 11:36:47 +00:00
|
|
|
|
return MusicBox.HighestNote.NoteNumber;
|
2017-12-02 20:47:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public int MinNoteNumber {
|
|
|
|
|
get
|
|
|
|
|
{
|
2017-12-03 11:36:47 +00:00
|
|
|
|
return MusicBox.LowestNote.NoteNumber;
|
2017-12-02 20:47:40 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-02 19:47:40 +00:00
|
|
|
|
public MusicBox MusicBox { get; private set; }
|
2017-11-30 22:45:39 +00:00
|
|
|
|
MidiFile midiFile;
|
|
|
|
|
|
2017-12-02 19:47:40 +00:00
|
|
|
|
public MusicBoxScoreGenerator(string filename, MusicBox inMusicBox)
|
2017-11-30 22:45:39 +00:00
|
|
|
|
{
|
2017-12-02 19:47:40 +00:00
|
|
|
|
MusicBox = inMusicBox;
|
2017-12-03 13:51:57 +00:00
|
|
|
|
midiFile = MidiFile.Read(filename);
|
2017-12-02 19:47:40 +00:00
|
|
|
|
|
|
|
|
|
foreach(Note note in AllNotes()) {
|
|
|
|
|
if (!MusicBox.IsValidNote(note))
|
2017-12-02 20:47:40 +00:00
|
|
|
|
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
|
|
|
|
}
|
2017-11-30 22:45:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Output(string destinationFilename)
|
|
|
|
|
{
|
2017-12-03 14:38:31 +00:00
|
|
|
|
Vector2 area = new Vector2(TrackLength, MusicBox.NoteCount).Multiply(scaleFactor);
|
2017-12-03 13:51:57 +00:00
|
|
|
|
Vector2 size = area.Add(offset.Multiply(2)).Add(new Vector2(100000, 1000));
|
2017-12-02 16:44:12 +00:00
|
|
|
|
|
|
|
|
|
SvgWriter svg = new SvgWriter(destinationFilename, size.X.ToString(), size.Y.ToString());
|
2017-12-03 13:51:57 +00:00
|
|
|
|
for(float i = 0; i < area.Y; i += scaleFactor.Y)
|
2017-12-02 14:38:49 +00:00
|
|
|
|
{
|
2017-12-03 13:51:57 +00:00
|
|
|
|
Vector2 start = offset.Add(new Vector2(0, i));
|
|
|
|
|
svg.WriteLine(start, start.Add(new Vector2(TrackLength * scaleFactor.X, 0)), "darkgreen", 1);
|
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())
|
|
|
|
|
{
|
2017-12-02 16:59:52 +00:00
|
|
|
|
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,
|
2017-12-03 14:38:31 +00:00
|
|
|
|
offset.Y + (MusicBox.NoteCount - MusicBox.NoteToBoxNumber(note)) * scaleFactor.Y
|
2017-11-30 23:03:55 +00:00
|
|
|
|
),
|
|
|
|
|
holeSize // radius
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
svg.Complete();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<Note> AllNotes()
|
|
|
|
|
{
|
2017-11-30 22:45:39 +00:00
|
|
|
|
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;
|
2017-11-30 22:45:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|