Store midi file

Hello to whom it may concern.
Hello My name is Dion Marinos

I have been a musician now for almost 40 years and now.
imdb link below.

for the last 18 months I have been getting into python coding.
As a python newb I have been working on a midi generator that generates midi
and places them in a folder of my choice on my computer.

As time went on my midi generator has become quite powerful as I continue to program my understanding of musical theory into the code.

Now this has nothing to do with AI as I know there are a lot of ai music generator coming onto the scene.

So this brings me to the question. I have been thinking about developing my app further to making it a service for other musicians around the world.
But I have no idea how how I would alter the code so as to have the midi file generated to the anvil website instead of my computer.
So right now the midi generator will make the midi file and place it in a folder on my computer , but if I use the anvil web site to run my app where would the midi file go ? A user logging into the site would be able to click a simple button then a file would be generated and made available for download.

Here is a simple script that would create a midi file and place it into a folder.

import os
import mido
from mido import Message, MidiFile, MidiTrack

def create_midi(folder_path, filename, ticks_per_note):
# Define the Ionian scale (C Major for simplicity)
ionian_scale = [60, 62, 64, 65, 67, 69, 71, 72] # MIDI notes for C4 to C5

# Create a new MIDI file and a track
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

# Add notes to the track
for note in ionian_scale:
    # Note on
    track.append(Message('note_on', note=note, velocity=64, time=0))
    # Note off (after the specified number of ticks)
    track.append(Message('note_off', note=note, velocity=64, time=ticks_per_note))

# Save the MIDI file
os.makedirs(folder_path, exist_ok=True)
mid.save(os.path.join(folder_path, filename))

Usage

create_midi(r’C:\Users\12369\PycharmProjects\midi solo’, ‘ionian_scale.mid’, 240)

If anyone has any Idea on how to proceed or any insight on how file storage to the anvil server via user downloadability works , your help would be appreciated
.

1 Like

Hi, and welcome. This sounds fascinating!

Similar to this Post, you could use a bytesio object.

3 Likes

Hello Owen . Thank you for the welcome and the advice.

Based on your code sample, I knocked up a quick demo:

Here’s a clone link for that:

7 Likes

Thank you very much! I was able to figure it out. I made a simple button and was able to successfully download a simple midi file. :grin:

Thanks for making this. I am not good at coding but I was able to show enough pictures to gpt 4.1 and worked out the solution although it was not as efficient as your example.

Here is what after many attempts and several hours what I was able to come up with using gpt 4.1 along with its picture upload feature.

import anvil
from ._anvil_designer import Form1Template
from anvil import *

class Form1(Form1Template):
def init(self, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)

def button_1_click(self, **event_args):
“”“This method is called when the button is clicked”“”
# Generate MIDI data on button click
midi_file = anvil.server.call(‘create_midi’, 240) # Call your server function to generate MIDI data

# Open the download link in a new browser tab
media.download(midi_file)

import anvil.server
import anvil
import io
import mido
from mido import Message, MidiFile, MidiTrack

@anvil.server.callable
def create_midi(ticks_per_note):

Define the Ionian scale (C Major for simplicity)

ionian_scale = [60, 62, 64, 65, 67, 69, 71, 72] # MIDI notes for C4 to C5

Create a new MIDI file and a track

mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

Add notes to the track

for note in ionian_scale:
# Note on
track.append(Message(‘note_on’, note=note, velocity=64, time=0))
# Note off (after the specified number of ticks)
track.append(Message(‘note_off’, note=note, velocity=64, time=ticks_per_note))

Save the MIDI data to a BytesIO object

midi_stream = io.BytesIO()
mid.save(file=midi_stream)
midi_stream.seek(0)

Create a Media object for the MIDI data

midi_file = anvil.BlobMedia(“audio/midi”, midi_stream.read(), name=“ionian_scale.mid”)

return midi_file