Normalizing Midi File Volumes

15 views
Skip to first unread message

Benny Chow

unread,
Jan 18, 2026, 2:24:39 PMJan 18
to disklavier-s...@googlegroups.com
Hi Guys

I use SweetMidi to play my collection of midi files on my Disklavier piano but the problem is that some songs are too soft and some are too loud.  I can change the note velocity globally in Sweet Midi settings but that makes for terrible user experience needing to mess with that after picking each song to play.

My solution so far is to modify each midi file using python + mido library and normalize them so they have the same median note velocity.  For each midi file, I try to target a median velocity of 100 (ranges from 0-127).  100 median combined with SweetMidi's note velocity adjustment (usually 65%) results in a volume that I enjoy.  If I want the piano to play louder, then I can increase SweetMidi's adjustment to 70-80% and all songs are uniformly louder.

I used ChatGPT to write the python scripts.  The script basically checks if the median velocity is below 100 (most are) and then adjusts the note velocities by:

1) Remap from a range of say 30-100 to 0-127 using a scaling factor
2) Adjust each node velocity by the same number to get a target median of 100

I'm pretty happy with the result and wondering if others have solved this volume normalization problem in a different or better way?

Thanks!
Benny


Mark Fontana

unread,
Jan 18, 2026, 6:54:47 PMJan 18
to disklavier-s...@googlegroups.com

Aiming for a *median* MIDI velocity of 100 seems too high.  Isn't that just making your tracks universally LOUD?  For such an approach, I would have expected a median value somewhere in the 70s to sound better.

As George Litterst pointed out earlier, the Disklavier expects practical dynamic range of around 30-95 for most content, maybe 25-100 for more expressive content, and extending to the low 100s for really forceful, concert-level playing.  Excursions outside of that range are rare.  At some point (probably around 110-115, depending on calibration), the PWM solenoid drive saturates anyway, so there really isn't any further difference in intensity from that point to 127.

There really isn't a one-size-fits-all remapping or normalization possible that will suit "all" MIDI files; it really depends on the content.  If the MIDI stream was recorded on a Disklavier to begin with, then no adjustment should be necessary.  Content for other solenoid-based player pianos tends to be fall within an acceptable range for the Disklavier as well (with some exceptions depending on when it was authored).  As for content created in a MIDI sequencer, or by AI, or from various non-Yamaha digital pianos and MIDI keyboards, all bets are off regarding both the dynamic range AND the velocity curve of intermediate values (it is incorrect to assume a linear mapping is always appropriate).  Very often, such mappings must be tweaked by ear, judging the intent of the piece, timbre, how subdued or strident the result is, etc.

Are you a software developer, or are you "vibe coding" your scripts?  Before discarding the original MIDI files, I recommend verifying that the scripts aren't doing anything detrimental to other aspects of the files (such as altering the delta times, stripping off metadata, etc.).  Also, I've generally seen better results from Anthropic's Claude Code than from ChatGPT for most coding exercises, but both seem fine for simple tasks.

Mark Fontana

George Frederick Litterst

unread,
Jan 18, 2026, 7:27:48 PMJan 18
to disklavier-s...@googlegroups.com
It sounds like you have a good thing going, Benny. I would point out 2 additional MIDI parameters:

All Disklaviers—except the Wagon Grand and the MX100A&B (and maybe the MX80/90)—respond to controller 7 (volume) and controller 11 (expression).

Natively, the Disklavier sets controller 7 = 100 when you make a recording and does not include controller 11. The default value of controller 11 = 127.

Thus, if you are getting MIDI files from any source other than a Disklavier, I would be certain to set controller 7 = 100 for the piano tracks and either delete controller 11 (if present) or set controller 11 = 127.

Controller 7 is very important. For virtual instruments, it sets an overall volume level so that you can balance one instrument against the others in a mix to another. It functions much like faders on a mixing board.

If controller 7 were to be “properly” implemented on a Disklavier, it would control how much the lid is open—which would be an absurdity, of course. Thus, the Disklavier engineers implemented controller 7 such that it globally raises and lowers the note-on velocities. As you can imagine, this can really mess with the resulting playback on the Disklavier.

Controller 11 is intended to be a secondary volume control for virtual instruments. The normal practice when creating a professional GM MIDI file is to set controller 7 once for every instrument in order to get the overall mix right, and then to use controller 11, optionally, to raise and lower the volume of instruments with sustained tones, such as strings and winds, as needed throughout the piece.

George (aka PianoBench)

--
To seek membership to this group, send an email to disklavier-suppor...@googlegroups.com.
---
You received this message because you are subscribed to the Google Groups "Disklavier Support Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to disklavier-support...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/disklavier-support-group/CAGZZM5d%2BsNJPsWajVWOikK_h1_vujZaq1P-Q58vyk_u6bPh1wg%40mail.gmail.com.

Joe Lindland

unread,
Jan 18, 2026, 7:47:02 PMJan 18
to disklavier-s...@googlegroups.com
Maybe I'm misunderstanding this but if you don't have too many song files, you can change the volume for each song in SMP.  Once done,  you then save the song,  prompted by SMP.  This way for each individual song you have set the volume to what is best for you.

Note,  I do this on my Mac.  I'm not sure about saving the songs if on an Ipad but you could transfer the modified files to your Ipad once done.

Best of luck,
Joe


Benny Chow

unread,
Jan 19, 2026, 2:13:41 AMJan 19
to disklavier-s...@googlegroups.com
Hello Mark, yes, I am a software developer and yes, I'm vibe coding =). For years I've wanted to find a way to batch process my midi collection but it wasn't until now with AI + Python + Mido, I could so easily chat with the LLM and it could teach me about how midi works and allow me to quickly test and hear different normalization algorithms on the piano.  A median velocity of 100 is of course too high for normal listening which is why I have SweetMidi set to 60% by default.  The midi file is encoded with a 100 median note velocity but SweetMidi scales that down to a 60 median velocity.  The problem with encoding a 60 median velocity in the midi file is that I can't get the piano to play louder.  SweetMidi seems to only scale the note velocities down but not up.  So, my solution is to encode all my midi files "loud" and use SweetMidi's global note velocity slider to uniformly control the volume.

Something else that the script does is include a lyric event that summarizes the before and after velocity metrics (min, max, median, avg, std dev/avg) so that I can click over to the lyric tab in SweetMidi and see what changes were made to the midi file.

Hello George, regarding CC7 and CC11, as you pointed out and as I learned through trial and error that my MX100 doesn't support those events.  So, in my case, those events are ignored and the math for calculating the final note velocity that the Disklavier receives is:  note on velocity * SweetMidi Scaling which I target for a per song median of 60.  But I guess if my controller did understand those events, then the math would be:

effective_level =
  velocity
  × (CC7 / 127)
  × (CC11 / 127)
  x SweetMidi Scaling

Hello Joe, I have thousands of midi files and I'd like to find a way to batch process them.  Opening each one in SweetMidi Pro and saving an updated velocity isn't a good workflow for me.  Besides velocity normalization, I also use Apple's Music API to add the release decade to the midi file names.  This way, if I'm in the mood for the 90s, I can search "1990s" in SweetMidi and the file name search pulls them up.

Thank you all for the feedback
Benny



George Litterst

unread,
Jan 19, 2026, 7:12:19 AMJan 19
to disklavier-s...@googlegroups.com, disklavier-s...@googlegroups.com
Good morning, Benny.

Slight correction: if you were to modify your MIDI algorithm to include CC7 and CC 11, the values should be:

CC7 = 100

CC11 = 127

Regards,
George (aka PianoBench)
Sent from my iPhone

On Jan 19, 2026, at 2:13 AM, Benny Chow <btc...@gmail.com> wrote:



Geoff Ward

unread,
Jan 19, 2026, 5:04:58 PMJan 19
to Disklavier Support Group
Hi Benny and others
Have you looked at the utilities created by Spencer Chase for modifying MIDI files.  He spent half a lifetime creating these utilities which are freely available on his website https://www.spencerserolls.com/Files4Download.html    .  Sadly, Spencer died about 6 months ago but his website lives on (for now).  I have used many of his utilities in the past and they still work with Window 11 (not for Apple).  The user interface is often not too friendly, but if you comprehend the information available on the site they become easy to use.  I suggest having a look at the MidiMod2 and MidiMod_equalizer programs.   With these you can modify a batch of files.
Kind regards

Geoff

Benny Chow

unread,
Jan 21, 2026, 2:36:11 AMJan 21
to disklavier-s...@googlegroups.com
After much trial and error and listening, I found this velocity normalization algorithm works very well across a variety of midi sources and allows them to all have the same volume on the Disklavier while still mostly preserving the original dynamics.

The algorithm from ChatGPT:

Practical approach (works well)

  1. Scale velocities so the median becomes 90.

  2. Apply a soft-knee compressor above a threshold (e.g. ~110) to tame only the loudest hits.

  3. Recompute the median and re-scale lightly back to 90 (compression can lower the median a bit).

  4. (Optional) Repeat steps 2–3 once more for a tighter median.


The chat history and python script are available here: https://chatgpt.com/share/6970750c-962c-8001-baf9-f86745ac9a5a

The soft knee compression at the upper velocities is critical to avoid notes slamming up against 127 and losing dynamic range there.

My script doesn't use CC7 events because my controller doesn't support it.  But if I ever upgrade one day, I'd probably set that to a fixed value and only use velocity to control the note loudness.

Geoff - Regarding Spencer Chase, his work and website were a legend!  I knew about him decades ago.  He's contributed so much to the midi community.  May he rest in peace.

Best
Benny



--
To seek membership to this group, send an email to disklavier-suppor...@googlegroups.com.
---
You received this message because you are subscribed to the Google Groups "Disklavier Support Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to disklavier-support...@googlegroups.com.

raymond dupuy

unread,
Jan 21, 2026, 7:31:42 AMJan 21
to disklavier-s...@googlegroups.com
Hello,
In the dkv utilities, you can find also « veloset » where you can adjust the velocity, file after file….
Best regards
Ray

Reply all
Reply to author
Forward
0 new messages