[report] an issue with channel numbers of midifile...

Hello,

it seems when a midifile has N channels, any midi channel which is set to channel number greater than N isn’t making sound.
To use percussion channel(channel number 10), we can’t have midifile which has less than 10 channels.

It’s not happening with FMOD 4. Please check into that.
Thanks in advance.

Hello,
I had your test files forwarded to me by Mathew.

I downloaded fmod programmer API 1.10, then used \FMOD Studio API Windows\api\lowlevel\examples\play_stream.cpp , I change the path from our sound to use your test files, but they both play correctly.

Can you show me an example of test code that has your problem? You can have midi that has less than 10 channels. I have 1 channel midi files here.

Hello Brett,

would you try this on both of FMOD 5 & 4 ?


// make all channels inaudible
for (int i = 0; i < 16; i++) {
sound->setMusicChannelVolume(i, 0);
}

// try to make all used channels audible
sound->getMusicNumChannels(&numOfUsedChannels);

for (int i = 0; i < numOfUsedChannels; i++) {
sound->setMusicChannelVolume(i, 1);
}


If the results were not same at your end, I guess the way FMOD 5 treats channel number internally is different with FMOD 4.
The channel numbers is re-assigned from 0 to ‘number of used channels’ in FMOD 4 regardless of original channel numbers in midifile.

In FMOD 5 however, the channel numbers seem to remain as they are.
If that’s right and there’s a proper reason to preserve them, it would be better for us to have a method to determine whether a channel ‘N’ actually exists in the midifile or not.

Hi,
Ok that’s different to the original question, which was that it just didn’t make sound. I see you’re talking about track vs channel indices now.

The track to channel mapping is preserved correctly in FMOD Studio. If you want to map a valid channel to an index, i suggest you use Sound::getTag. it gives you information about the midi file. The 9 track song skips a channel at track 9 and uses channel 10 for that.

Here’s some example getTag code

   result = gSound[count]->getNumTags(&numtags, 0);
    CHECK_RESULT(result);
    for (count2 = 0; count2 < numtags; count2++)
    {
        FMOD_TAG tag;

        result = gSound[count]->getTag(0, count2, &tag);
        CHECK_RESULT(result);

        if (tag.datatype == FMOD_TAGDATATYPE_STRING)
        {
            printf("[tag - string] %-28s : %s\n", tag.name, tag.data);
        }
        else if (tag.datatype == FMOD_TAGDATATYPE_INT)
        {
            if (tag.datalen == 8)
            {
                printf("[tag -  qword] %-28s : %I64d\n", tag.name, *((long long *)tag.data));
            }
            else if (tag.datalen == 4)
            {
                printf("[tag -  dword] %-28s : %d\n", tag.name, *((int *)tag.data));
            }
            else if (tag.datalen == 2)
            {
                printf("[tag -   word] %-28s : %d\n", tag.name, *((short *)tag.data));
            }
        }
    }        

The ‘ch’ result for the track name is stored as a string, so you will have to pull the number out of that, and map the track to channel index using this info. those channel numbers are what you can use in Sound::setMusicChannelVolume.

regards,

Hi Brett,

you’re right. I was asking a wrong question at first.
Sorry for that and thanks for helping me understand what’s going on inside of FMOD 5.
(Maybe I need to change the topic of this post to proper one.)

Using the example code, I got these with my midifile which has only 2 tracks.
Track 1 is assigned to channel 3 and Track 2 is assigned to channel 4.
(midifile - https://www.dropbox.com/s/wynbio0an7qlrrn/midi_channel3%264.mid?dl=0)


[tag - string] Track 0 Name : midi_channel3&4 -----------> name of midifile
[tag - string] Track 1 Name : The Black Cat Rag -----------> name of track 1
[tag - string] Track 2 Name : by F. Wooster & E. Smith (1905) -----------> name of track 2
[tag - dword] Number of channels : 2


Total number of tags is 4 so I think they are all I can get.
Would you mind letting me know where I can find the assigned channel numbers of each track, to use setMusicChannelVolume?
(i.e. ‘3’ for track 1 and ‘4’ for track 2)

Thanks in advance.

Ok I looked into it - this is an old issue, apparently the behaviour USED to be the way you expected it to be, but that caused a problem, if you knew track 9 was drums, you couldnt just say ‘set volume on channel 9’ to mute the drums, it would have been remapped.

ie
Muting midi drums channel with setMusicChannelVolume - Unity - FMOD Forums has more info

The getMusicNumChannels is now ‘information only’, and you should basically just set all 16 tracks.
I could add a new DWORD tag called ‘Track %d Channel’ with the tag data value being the channel number, that you can pass to setMusicChannelVolume function if that would help.

Usually you know what tracks you want to alter volumes on, because you wrote the music, unless this is for some sort of media player that handles generic midi files.

Thanks for sharing context regarding this.

I’ve made and been using a tool based on FMOD 4 for monitoring midi & dls and microtuning channel volumes(Because the sound balance of midi playback from FMOD was slightly different from DAW due to the differences of panning and/or velocity response curves, I guess), looping points, music speed, DSP parameters and exporting them as a preset so that client can use them in game.
You can imagine 16 slidebars(enabled only for used channels actually) for each channels and another knobs & slidebars for rest of parrameters.

Since it seems obvious we’ll be using FMOD Studio & Low Level API soon in some projects, so I’m in the middle of upgrading the tool for FMOD 5. That’s why I was confused when I met this behavior.

If it’s not trivial to expose real channel numbers to the tag, I would use midi-dedicated library to get them ahead of actual loading and exporting.

Thanks.

its pretty trivial, I might add it and link a custom build for you soon.

Glad to hear that. Would you consider that this addition to be included from the next release, rather than custom build? I’ve already had a workaround for this from outside of FMOD but I think if channel numbers were being preserved, we should be accessible to them, by FMOD itself. Thank you very much.

I’ve attached a pre-release build to your account. It now includes a channel mask tag in the tags. I’ve also updated FMOD_TAG docs to be clearer.

The example for your case in the docs is.

“FMOD_TAGTYPE_MIDI remarks. A midi file contains 16 channels. Not all of them are used, or in order. Use the tag ‘Channel mask’ and ‘Number of channels’ to find the channels used, to use with Sound::setMusicChannelVolume /
Sound::getMusicChannelVolume. For example if the mask is 1001b, there are 2 channels, and channel 0 and channel 3 are the 2 channels used with the above functions.”

The prerelease will become a public release at the end of the month.