Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Arachno SoundFont Drum Kits #41

Open
chaojian-zhang opened this issue Oct 13, 2023 · 7 comments
Open

[Question] Arachno SoundFont Drum Kits #41

chaojian-zhang opened this issue Oct 13, 2023 · 7 comments

Comments

@chaojian-zhang
Copy link

chaojian-zhang commented Oct 13, 2023

Hi, thanks a lot for this amazing library! It's awesome馃憤, and I've used it in my personal project here (Fluent Synth)馃槅.
In general it is very straightforward and works great out of the box, but I do notice a difference in playback compared to VLC's FluidSynth. At the moment I am still looking into whether it has to do with my setup or it's just the two platforms interpret MIDI files different.

Anyway, my question here is related to Arachno SoundFont - Version 1.0: in the documentation of this sound font it mentioned there are some "drum kits" available:

image

I wonder how we can use those drum kits through Melty Synth? (In the documentation it mentioned General MIDI has Music Box or instrument number 10 used as default for drum kit, but not further information on that)
If you have any information on how those drum kits are defined inside a MIDI file that would also be very helpful!

@chaojian-zhang
Copy link
Author

chaojian-zhang commented Oct 13, 2023

By the way, as to the first part of my description above - "sound difference between VLC and Melty Synth", I was using NAudio for play back and testing Clickteam - Klik & Play - Romeo - Medieval Tune (Greensleeves).mid that comes with arachno-soundfont-1.0 inside the "MIDI Files" folder. You can reproduce and hear it using code below (I am using NAudio for playback):

byte[] ConvertChannels(float[] left, float[] right)
{
	var bytes = left
		.Zip(right, (left, right) => (Left: left, Right: right))
		.SelectMany(channels => {
			// This automatically handles both negative and positive spectrum 
			// because channels value could be negative
			var sampleL = (short)(channels.Left * short.MaxValue);
			var sampleR = (short)(channels.Right * short.MaxValue);
			
			var bytesL = BitConverter.GetBytes(sampleL);
			var bytesR = BitConverter.GetBytes(sampleR);
			// Each sample is just byte sequence of a short
			// Samples for each channel follows each other
			return new byte[] {
				bytesL[0], bytesL[1], 
				bytesR[0], bytesR[1]
			};
		})
		.ToArray();
	return bytes;
}

WaveOutEvent Play(int sampleRate, float[] left, float[] right)
{
	var bytes = ConvertChannels(left, right);
	var memoryStream = new MemoryStream(bytes);
	var waveStream = new RawSourceWaveStream(memoryStream, new WaveFormat(sampleRate, 16, 2));
	var outputDevice = new WaveOutEvent();
	
	outputDevice.Init(waveStream);
	outputDevice.Play();
	return outputDevice;
}
var sampleRate = 44100;
var synthesizer = new Synthesizer(soundFontFilePath, sampleRate);
var midiFile = new MidiFile(@"Clickteam - Klik & Play - Romeo - Medieval Tune (Greensleeves).mid");

var sequencer = new MidiFileSequencer(synthesizer);
sequencer.Play(midiFile, false);

var left = new float[(int)(sampleRate * midiFile.Length.TotalSeconds)];
var right = new float[(int)(sampleRate * midiFile.Length.TotalSeconds)];
sequencer.Render(left, right);

var waveOutEvent = Play(sampleRate, left);

@sinshu
Copy link
Owner

sinshu commented Oct 13, 2023

If this library is helpful to you, I'd be delighted 馃槉

To change the type of drum, perform a program change on the drum channel (9).
For example, the following code changes the drum to "Room Drum Kit" (No. 8).

synthesizer.ProcessMidiMessage(9, 0xC0, 8, 0);

@sinshu
Copy link
Owner

sinshu commented Oct 13, 2023

Regarding the MIDI file you provided, I listened to it using MeltySynth's MIDI playback sample code and didn't encounter any issues (although the nostalgia of the song almost made me cry). Are you experiencing glitches during playback? Or does the sound quality in specific parts differ compared to other playback software? If you could elaborate a bit more, I might be able to help.

@chaojian-zhang
Copy link
Author

If this library is helpful to you, I'd be delighted 馃槉

To change the type of drum, perform a program change on the drum channel (9). For example, the following code changes the drum to "Room Drum Kit" (No. 8).

synthesizer.ProcessMidiMessage(9, 0xC0, 8, 0);

Thank you very much for quick reply!
I tried this and it worked!

Can we have more than one drum channel, or specify custom drum channels (e.g. use channel 11 for drum as well)?

@chaojian-zhang
Copy link
Author

chaojian-zhang commented Oct 14, 2023

Regarding the MIDI file you provided, I listened to it using MeltySynth's MIDI playback sample code and didn't encounter any issues (although the nostalgia of the song almost made me cry). Are you experiencing glitches during playback? Or does the sound quality in specific parts differ compared to other playback software? If you could elaborate a bit more, I might be able to help.

Memory tricks us - hopefully, that's sweetness that you felt.

To be clear, Melty synth handles MIDI synthesization flawlessly without any issues or glitches! I was referring more to the sound quality, when compared to VLC (I don't have other playback software to compare with at the moment).

I have converted the same MIDI into mp3 file and opened the first 10s in Audacity (top is from Melty Synth, bottom is from VLC's Fluid Synth), as you can see, VLC produce in general higher volume. But that's not the only difference. The version from VLC seems to have the violin/cello part enhanced.

image

This is the same samples in spectrogram view:

Spectrogram

I upload them as mp4 because that's the format Github supports.

This is the result from Melty Synth:

FluentMelty_cut.mp4

This is the result from VLC:

VLCFluid_cut.mp4

First 3 seconds (waveform shown in dB) from Melty Synth:

image

First 3 seconds (waveform shown in dB) from VLC:

image

In general, the base from VLC is stronger and fuller. I don't know whether that's a result of VLC configuration or something from the MIDI file specifies that. Below shows my VLC (version 3.0.11 Vetinari) configuration for Fluid Synth:

image

(Not sure whether it's related to Chorus and Reverb - I tried to turn them off and it doesn't seem to have any effect)

@sinshu
Copy link
Owner

sinshu commented Oct 14, 2023

First, if you want to increase the overall volume, you can do so by setting the Synthesizer.MasterVolume property to a larger value.

Regarding the violin sounding more prominent in VLC, it is believed that the chorus effect implemented in FluidSynth is causing this. The corresponding instrument in Arachno SoundFont is set to have a chorus of 100%, which appears to be pushing up the volume. In fact, if you turn off the chorus in VLC鈥檚 settings, you will get roughly the same volume balance as MeltySynth.

The chorus in MeltySynth is different from FluidSynth. This is not a matter of which one is correct, but rather a matter of preference.

@sinshu
Copy link
Owner

sinshu commented Oct 15, 2023

Can we have more than one drum channel, or specify custom drum channels (e.g. use channel 11 for drum as well)?

MeltySynth primarily offers compatibility with General MIDI 1. In General MIDI 1, the drum channel is fixed at 10 and cannot be increased without some kind of extension. However, in SoundFont, drum presets are stored in bank number 128. Therefore, by sending a command to set the bank number to 128 for a specific channel, as shown below, you can use drums on that channel.

// Change channel[0] to drums
synthesizer.ProcessMidiMessage(0, 0xB0, 0, 128);

Note that this method may not work on other synthesizers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants