Question

I have downloaded https://code.google.com/p/android-midi-lib/ in an attempt to play solid strings sounds for long durations. I would like to understand how to use MIDI channels other than the default grand piano. Channels should be the answer. Changing them doesn't seem to have an effect. Do all 16 channels sound like a grand piano in Android? Or am I missing something?!?

I have adapted the example file write routine from the referenced project. I have tried 5 MIDI channels. They all sound like channel 0. I have had consistent results on a Droid 2, and a S3.

    MidiTrack tempoTrack = new MidiTrack();
    MidiTrack noteTrack = new MidiTrack();

    // 2. Add events to the tracks
    // 2a. Track 0 is typically the tempo map
    TimeSignature ts = new TimeSignature();
    ts.setTimeSignature(4, 4, TimeSignature.DEFAULT_METER, TimeSignature.DEFAULT_DIVISION);

    Tempo t = new Tempo();
    t.setBpm(bpm);

    tempoTrack.insertEvent(ts);
    tempoTrack.insertEvent(t);

    for(int i = 21; i < 108; i += 5)
    {
        int channel = 8, pitch = 1 + i, velocity = 100;
        noteTrack.insertNote(channel, pitch + 2, velocity, noteTrack.getLengthInTicks(), 120);
    }

    // 3. Create a MidiFile with the tracks we created
    ArrayList<MidiTrack> tracks = new ArrayList<MidiTrack>();
    tracks.add(tempoTrack);
    tracks.add(noteTrack);

    MidiFile midi = new MidiFile(MidiFile.DEFAULT_RESOLUTION, tracks);
    // 4. Write the MIDI data to a file
    //omitted for clarity

    try {
        FileInputStream is = new FileInputStream(output);
        mediaPlayer.reset();
        mediaPlayer.setDataSource(is.getFD()); //there are issues if you pass in the file name
        mediaPlayer.prepare();
    } catch (Exception e) { 
        System.err.println(e);
    }

I'm not spot on my MIDI file format. But, it appears as thought the channel is being written to the file that is later read by MediaPlayer. I have verified that the channel information is correct when it's written to the file. I see two suspects: MediaPlayer, and the system MIDI engine. I'm not sure where to focus...

here's the code that should write the channel info (ChannelEvent) to the MIDI file:

@Override
public void writeToFile(OutputStream out, boolean writeType) throws IOException
{
    super.writeToFile(out, writeType);

    if(writeType)
    {
        int typeChannel = (mType << 4) + mChannel;
        out.write(typeChannel);
    }

    out.write(mValue1);
    if(mType != PROGRAM_CHANGE && mType != CHANNEL_AFTERTOUCH)
    {
        out.write(mValue2);
    }
}

any thoughts?

Was it helpful?

Solution

In MIDI, channels are not identical with instruments.

Each channel can be configured with its own instrument. To do this, send a ProgramChange message to that channel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top