Created
March 3, 2025 23:54
-
-
Save r618/c62b9a6d84896e1303ccbd6d01c89b27 to your computer and use it in GitHub Desktop.
few czech folk/children songs -> MIDI basic generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
string outputFile = args[0]; | |
GenerateMidiFile(outputFile); | |
Console.WriteLine($"MIDI file saved as {outputFile}"); | |
} | |
const int NOTE_C4 = 60; // C4 | |
const int NOTE_D4 = 62; // D4 | |
const int NOTE_E4 = 64; // E4 | |
const int NOTE_F4 = 65; // F4 | |
const int NOTE_G4 = 67; // G4 | |
const int NOTE_A4 = 69; // A4 | |
const int NOTE_H4_FLAT = 70; | |
const int NOTE_H4 = 71; // B4 (H in Czech notation) | |
const int NOTE_C5 = 72; // C5 | |
// Define note durations (in MIDI ticks) | |
const int EIGHTH_NOTE = QUARTER_NOTE / 2; | |
const int QUARTER_NOTE = 480; // Standard MIDI resolution | |
const int HALF_NOTE = QUARTER_NOTE * 2; | |
const int HALF_AND_QUARTER_NOTE = QUARTER_NOTE * 3; | |
const int WHOLE_NOTE = HALF_NOTE * 2; | |
const int REST = -1; // Using -1 as a sentinel value to indicate a rest | |
// Define the notes according to the sheet music for Běžela Ovečka | |
// Format: [note, duration] | |
static readonly object[] bezela_ovecka_notes = new[] | |
{ | |
// First line | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C5, Duration = HALF_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_H4, Duration = HALF_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
// Second line | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = HALF_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE } | |
}; | |
// The notes for "Kočka leze dírou" song | |
static readonly object[] kocka_leze_notes = new[] | |
{ | |
// First measure - four eighth notes | |
new { Note = NOTE_C4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE}, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
// Second measure - two quarter notes | |
new { Note = NOTE_G4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = HALF_NOTE}, | |
// Third measure - two quarter notes | |
new { Note = NOTE_A4, Duration = HALF_NOTE}, | |
new { Note = NOTE_A4, Duration = HALF_NOTE}, | |
// Fourth measure - half note | |
new { Note = NOTE_G4, Duration = WHOLE_NOTE }, | |
// Fifth measure - two quarter notes | |
new { Note = NOTE_A4, Duration = HALF_NOTE}, | |
new { Note = NOTE_A4, Duration = HALF_NOTE}, | |
// Sixth measure - half note | |
new { Note = NOTE_G4, Duration = WHOLE_NOTE }, | |
// Seventh measure - four quarter notes | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE}, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
// Eighth measure - two quarter notes | |
new { Note = NOTE_E4, Duration = HALF_NOTE }, | |
new { Note = NOTE_E4, Duration = HALF_NOTE}, | |
// Ninth measure - two quarter notes | |
new { Note = NOTE_D4, Duration = HALF_NOTE}, | |
new { Note = NOTE_D4, Duration = HALF_NOTE}, | |
// Tenth measure - half note (with repeat sign) | |
new { Note = NOTE_G4, Duration = WHOLE_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE}, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
// Eighth measure - two quarter notes | |
new { Note = NOTE_E4, Duration = HALF_NOTE }, | |
new { Note = NOTE_E4, Duration = HALF_NOTE}, | |
// Ninth measure - two quarter notes | |
new { Note = NOTE_D4, Duration = HALF_NOTE}, | |
new { Note = NOTE_D4, Duration = HALF_NOTE}, | |
// Final measure after repeat - half note | |
new { Note = NOTE_C4, Duration = WHOLE_NOTE } | |
}; | |
static readonly object[] prsi_prsi_notes = new[] | |
{ | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = HALF_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C4, Duration = HALF_NOTE }, | |
}; | |
static readonly object[] pec_nam_spadla_notes = new[] | |
{ | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = HALF_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = HALF_NOTE }, | |
}; | |
static readonly object[] tluce_bubenicek_notes = new[] | |
{ | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_D4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_E4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_E4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = REST, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_C5, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_E4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_D4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_D4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_C4, Duration = QUARTER_NOTE }, | |
new { Note = REST, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4_FLAT, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_A4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_H4_FLAT, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_A4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_C4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_C4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_D4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_E4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = REST, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_G4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_C5, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_E4, Duration = EIGHTH_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = REST, Duration = QUARTER_NOTE }, | |
}; | |
static readonly object[] komari_se_zenili_notes = new[] | |
{ | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = HALF_NOTE }, | |
new { Note = NOTE_D4, Duration = HALF_NOTE }, | |
new { Note = NOTE_F4, Duration = HALF_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = HALF_NOTE }, | |
new { Note = NOTE_D4, Duration = HALF_NOTE }, | |
new { Note = NOTE_F4, Duration = HALF_NOTE }, | |
new { Note = NOTE_E4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_D4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C5, Duration = HALF_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_AND_QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = HALF_NOTE }, | |
new { Note = NOTE_F4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = WHOLE_NOTE }, | |
new { Note = NOTE_C4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C5, Duration = HALF_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_AND_QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C5, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_H4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = HALF_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_A4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_G4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_F4, Duration = QUARTER_NOTE }, | |
new { Note = NOTE_E4, Duration = HALF_NOTE }, | |
new { Note = NOTE_D4, Duration = HALF_NOTE }, | |
new { Note = NOTE_C4, Duration = WHOLE_NOTE }, | |
}; | |
static void GenerateMidiFile(string outputPath) | |
{ | |
// Create a new MIDI file with one track | |
MidiEventCollection midiEvents = new MidiEventCollection(1, QUARTER_NOTE); | |
midiEvents.AddTrack(); | |
midiEvents.AddTrack(); | |
// Add tempo and time signature info | |
long absoluteTime = 0; | |
// Set tempo to 120 BPM | |
var tempoEvent = new TempoEvent(500000, absoluteTime); // 500000 microseconds = 120 BPM | |
midiEvents[0].Add(tempoEvent); | |
// Set time signature to 4/4 | |
var timeSignature = new TimeSignatureEvent(absoluteTime, 4, 4, 24, 8); | |
midiEvents[0].Add(timeSignature); | |
// Set instrument to Acoustic Grand Piano (General MIDI program 0) | |
var patchEvent = new PatchChangeEvent(absoluteTime, 1, 0); | |
midiEvents[1].Add(patchEvent); | |
// Add notes to the MIDI file | |
absoluteTime = 0; | |
foreach (dynamic note in komari_se_zenili_notes) | |
{ | |
if (note.Note != REST) | |
{ | |
// Note On event | |
var noteOnEvent = new NoteOnEvent(absoluteTime, 1, note.Note, 100, note.Duration); | |
midiEvents[1].Add(noteOnEvent); | |
// Note Off event (immediately after the note duration) | |
var noteOffEvent = new NoteEvent(absoluteTime + note.Duration, 1, MidiCommandCode.NoteOff, note.Note, 0); | |
midiEvents[1].Add(noteOffEvent); | |
} | |
// Move absolute time forward by the note duration | |
absoluteTime += note.Duration; | |
} | |
// Add end of track event | |
var endOfTrackEvent = new MetaEvent(MetaEventType.EndTrack, 0, absoluteTime); | |
midiEvents[1].Add(endOfTrackEvent); | |
// Save MIDI file | |
MidiFile.Export(outputPath, midiEvents); | |
} | |
} |
Author
r618
commented
Mar 3, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment