Search in sources :

Example 1 with PitchedInstrument

use of com.xenoage.zong.core.instrument.PitchedInstrument in project Zong by Xenoage.

the class MidiChordPlayer method playNote.

/**
 * Plays a single note.
 */
public void playNote(Pitch pitch, Instrument instrument, byte velocity) {
    if (instrument instanceof PitchedInstrument)
        setMidiprogram(((PitchedInstrument) instrument).getMidiProgram());
    int midipitch = MidiTools.getNoteNumber(pitch);
    channel.noteOn(midipitch, velocity);
    final Pitch p = pitch;
    final Timer timer = new Timer();
    timer.schedule(new TimerTask() {

        @Override
        public void run() {
            stopSingleNote(p);
            timer.cancel();
        }
    }, duration);
}
Also used : Timer(java.util.Timer) TimerTask(java.util.TimerTask) PitchedInstrument(com.xenoage.zong.core.instrument.PitchedInstrument) Pitch(com.xenoage.zong.core.music.Pitch)

Example 2 with PitchedInstrument

use of com.xenoage.zong.core.instrument.PitchedInstrument in project Zong by Xenoage.

the class Test72b method testTransposes.

@Test
public void testTransposes() {
    for (int iPart : range(expectedTransposes.length)) {
        Part part = score.getStavesList().getParts().get(iPart);
        PitchedInstrument instrument = (PitchedInstrument) part.getFirstInstrument();
        assertEquals("Part " + iPart, expectedTransposes[iPart], instrument.getTranspose());
    }
}
Also used : Part(com.xenoage.zong.core.music.Part) PitchedInstrument(com.xenoage.zong.core.instrument.PitchedInstrument) Test(org.junit.Test)

Example 3 with PitchedInstrument

use of com.xenoage.zong.core.instrument.PitchedInstrument in project Zong by Xenoage.

the class MidiConverter method convertToSequence.

private MidiSequence<T> convertToSequence() {
    // compute mapping of staff indices to channel numbers
    channelMap = createChannelMap(score);
    // compute repetitions (repeat barlines, segnos, ...)
    repetitions = RepetitionsFinder.findRepetitions(score);
    // compute the mappings from application time to MIDI time
    timeMap = new TimeMapper(score, repetitions, options.midiSettings.resolutionFactor).createTimeMap();
    // find all dynamics
    dynamics = DynamicsFinder.findDynamics(score, new DynamicsInterpretation(), repetitions);
    // one track for each staff and one system track for program changes, tempos and so on,
    // and another track for the metronome
    int stavesCount = score.getStavesCount();
    int tracksCount = stavesCount + 1;
    Integer metronomeTrack = null;
    if (options.metronome) {
        metronomeTrack = tracksCount;
        tracksCount++;
    }
    // resolution in ticks per quarter
    resolution = score.getDivisions() * options.midiSettings.getResolutionFactor();
    // init writer
    writer.init(tracksCount, resolution);
    // set MIDI programs and init volume and pan
    for (val part : score.getStavesList().getParts()) {
        val instrument = part.getFirstInstrument();
        int partFirstStaff = score.getStavesList().getPartStaffIndices(part).getStart();
        int channel = channelMap.getChannel(partFirstStaff);
        if (channel != unused) {
            if (instrument instanceof PitchedInstrument) {
                val pitchedInstrument = (PitchedInstrument) instrument;
                writer.writeProgramChange(systemTrackIndex, channel, 0, (pitchedInstrument).getMidiProgram());
            }
            writer.writeVolumeChange(systemTrackIndex, channel, 0, instrument.getVolume());
            writer.writePanChange(systemTrackIndex, channel, 0, instrument.getPan());
        }
    }
    // fill tracks
    for (int iStaff : range(stavesCount)) {
        int channel = channelMap.getChannel(iStaff);
        if (channel == unused)
            // no MIDI channel left for this staff
            continue;
        Staff staff = score.getStaff(iStaff);
        int voicesCount = staff.getVoicesCount();
        // first track is reserved; see declaration of tracksCount
        int track = iStaff + 1;
        for (int iRepetition : range(repetitions)) {
            val rep = repetitions.get(iRepetition);
            // TODO
            int transpose = 0;
            for (int iMeasure : range(rep.start.getMeasure(), rep.end.getMeasure())) {
                if (iMeasure == score.getMeasuresCount())
                    continue;
                Measure measure = staff.getMeasure(iMeasure);
                for (int iVoice : range(measure.getVoices())) {
                    writeVoice(atVoice(iStaff, iMeasure, iVoice), iRepetition);
                }
            }
        }
    }
    // write events for time mapping between the MIDI sequence and the score
    if (options.addTimeEvents)
        writePlaybackControlEvents();
    // write metronome track
    if (options.metronome)
        writeMetronomeTrack(metronomeTrack);
    return writer.finish(metronomeTrack, timeMap);
}
Also used : lombok.val(lombok.val) PitchedInstrument(com.xenoage.zong.core.instrument.PitchedInstrument) TimeMapper(com.xenoage.zong.io.midi.out.time.TimeMapper) DynamicsInterpretation(com.xenoage.zong.io.midi.out.dynamics.DynamicsInterpretation)

Example 4 with PitchedInstrument

use of com.xenoage.zong.core.instrument.PitchedInstrument in project Zong by Xenoage.

the class InstrumentsReaderTest method testInstrumentChanges.

/**
 * Read the file "InstrumentChanges.xml".
 * It must contain 3 instruments, namely a Clarinet in B, an Alto Sax in Eb
 * and a Trombone in C. Check also the transpositons and see if the instrument
 * changes happen at the right positions.
 */
@Test
public void testInstrumentChanges() {
    Score score = MusicXmlScoreFileInputTest.loadXMLTestScore("InstrumentChanges.xml");
    Part part = score.getStavesList().getParts().get(0);
    assertEquals(3, part.getInstruments().size());
    // clarinet
    PitchedInstrument instr0 = (PitchedInstrument) part.getInstruments().get(0);
    assertEquals("Clarinet in Bb", instr0.getName());
    assertEquals(new Integer(-1), instr0.getTranspose().getDiatonic());
    assertEquals(-2, instr0.getTranspose().getChromatic());
    // altosax
    PitchedInstrument instr1 = (PitchedInstrument) part.getInstruments().get(1);
    assertEquals("Alto Saxophone", instr1.getName());
    assertEquals(new Integer(-5), instr1.getTranspose().getDiatonic());
    assertEquals(-9, instr1.getTranspose().getChromatic());
    // trombone
    PitchedInstrument instr2 = (PitchedInstrument) part.getInstruments().get(2);
    assertEquals("Trombone", instr2.getName());
    assertEquals(new Integer(0), instr2.getTranspose().getDiatonic());
    assertEquals(0, instr2.getTranspose().getChromatic());
    // instrument changes in measures 1, 2 and 3
    Measure measure = score.getMeasure(atMeasure(0, 1));
    assertEquals(instr1, getInstrumentChangeAtBeat0(measure).getInstrument());
    measure = score.getMeasure(atMeasure(0, 2));
    assertEquals(instr2, getInstrumentChangeAtBeat0(measure).getInstrument());
    measure = score.getMeasure(atMeasure(0, 3));
    assertEquals(instr0, getInstrumentChangeAtBeat0(measure).getInstrument());
}
Also used : Score(com.xenoage.zong.core.Score) Part(com.xenoage.zong.core.music.Part) PitchedInstrument(com.xenoage.zong.core.instrument.PitchedInstrument) MP.atMeasure(com.xenoage.zong.core.position.MP.atMeasure) Measure(com.xenoage.zong.core.music.Measure) MusicXmlScoreFileInputTest(com.xenoage.zong.io.musicxml.in.MusicXmlScoreFileInputTest) Test(org.junit.Test)

Example 5 with PitchedInstrument

use of com.xenoage.zong.core.instrument.PitchedInstrument in project Zong by Xenoage.

the class ChannelMapper method createReusedChannels.

/**
 * Share channel for parts with the same instrument (MIDI program).
 * If none is left, the part is ignored (channel index = {@link ChannelMap#unused}).
 * All unpitched parts get channel 10.
 */
private static int[] createReusedChannels(Score score) {
    int[] staffChannels = new int[score.getStavesCount()];
    int nextFreeChannel = 0;
    HashMap<Integer, Integer> programToDeviceMap = map();
    for (Part part : score.getStavesList().getParts()) {
        boolean isPitched = isPitched(part);
        // find channel
        int channel;
        if (isPitched) {
            // pitched part: create new channel or reuse existing channel
            val pitchedInstr = (PitchedInstrument) part.getFirstInstrument();
            int program = pitchedInstr.getMidiProgram();
            channel = notNull(programToDeviceMap.get(program), nextFreeChannel);
            if (channel >= maxChannelsCount) {
                // no more channel left for this part
                channel = unused;
            } else if (channel == nextFreeChannel) {
                // new channel created: increment next channel number and remember program
                // don't use channel 10
                nextFreeChannel = nextFreeChannel + 1 + (nextFreeChannel + 1 == channel10 ? 1 : 0);
                programToDeviceMap.put(program, channel);
            }
        } else {
            // unpitched part: always use channel 10
            channel = channel10;
        }
        // apply channel to all staves
        for (int iStaff : score.getStavesList().getPartStaffIndices(part).getRange()) {
            staffChannels[iStaff] = channel;
        }
    }
    return staffChannels;
}
Also used : lombok.val(lombok.val) Part(com.xenoage.zong.core.music.Part) PitchedInstrument(com.xenoage.zong.core.instrument.PitchedInstrument)

Aggregations

PitchedInstrument (com.xenoage.zong.core.instrument.PitchedInstrument)12 Part (com.xenoage.zong.core.music.Part)6 Test (org.junit.Test)4 Instrument (com.xenoage.zong.core.instrument.Instrument)3 UnpitchedInstrument (com.xenoage.zong.core.instrument.UnpitchedInstrument)3 lombok.val (lombok.val)3 Score (com.xenoage.zong.core.Score)2 InstrumentChange (com.xenoage.zong.core.music.InstrumentChange)2 MxlMidiInstrument (com.xenoage.zong.musicxml.types.MxlMidiInstrument)2 MxlScoreInstrument (com.xenoage.zong.musicxml.types.MxlScoreInstrument)2 PartAdd (com.xenoage.zong.commands.core.music.PartAdd)1 Transpose (com.xenoage.zong.core.instrument.Transpose)1 Measure (com.xenoage.zong.core.music.Measure)1 Pitch (com.xenoage.zong.core.music.Pitch)1 Clef (com.xenoage.zong.core.music.clef.Clef)1 Key (com.xenoage.zong.core.music.key.Key)1 TraditionalKey (com.xenoage.zong.core.music.key.TraditionalKey)1 TimeSignature (com.xenoage.zong.core.music.time.TimeSignature)1 MP.atMeasure (com.xenoage.zong.core.position.MP.atMeasure)1 DynamicsInterpretation (com.xenoage.zong.io.midi.out.dynamics.DynamicsInterpretation)1