/** * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2013 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.catrobat.musicdroid.test.note.midi; import android.test.AndroidTestCase; import com.leff.midi.MidiFile; import com.leff.midi.MidiTrack; import com.leff.midi.event.MidiEvent; import com.leff.midi.event.NoteOff; import com.leff.midi.event.NoteOn; import com.leff.midi.event.ProgramChange; import com.leff.midi.event.meta.Tempo; import com.leff.midi.event.meta.Text; import org.catrobat.musicdroid.note.Instrument; import org.catrobat.musicdroid.note.NoteEvent; import org.catrobat.musicdroid.note.Project; import org.catrobat.musicdroid.note.Track; import org.catrobat.musicdroid.note.midi.MidiException; import org.catrobat.musicdroid.note.midi.ProjectToMidiConverter; import org.catrobat.musicdroid.test.note.midi.testutil.MidiFileTestDataFactory; import org.catrobat.musicdroid.test.note.testutil.ProjectTestDataFactory; import org.catrobat.musicdroid.test.utils.Reflection; import org.catrobat.musicdroid.test.utils.Reflection.ParameterList; import java.util.ArrayList; import java.util.Iterator; public class ProjectToMidiConverterTest extends AndroidTestCase { public void testAddInstrumentAndGetChannel1() throws MidiException { ProjectToMidiConverter converter = new ProjectToMidiConverter(); int[] expectedChannels = { 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; Instrument[] instruments = { Instrument.ACCORDION, Instrument.ACCORDION, Instrument.ACOUSTIC_BASS, Instrument.ACOUSTIC_BASS, Instrument.ACOUSTIC_GRAND_PIANO, Instrument.AGOGO_BELLS, Instrument.APPLAUSE, Instrument.BAGPIPE, Instrument.BANJO, Instrument.BASSOON, Instrument.BRASS_SECTION, Instrument.CELLO, Instrument.CHURCH_ORGAN, Instrument.CLARINET, Instrument.DISTORTION_GUITAR, Instrument.ELECTRIC_BASS_FINGER, Instrument.FX_1_RAIN, Instrument.FX_8_SCI_FI }; for (int i = 0; i < instruments.length; i++) { ParameterList parameters = new ParameterList(instruments[i]); int actualChannel = (Integer) Reflection.invokeMethod(converter, "addInstrumentAndGetChannel", parameters); assertEquals(expectedChannels[i], actualChannel); } } public void testAddInstrumentAndGetChannel2() throws MidiException { ProjectToMidiConverter converter = new ProjectToMidiConverter(); Instrument[] instruments = { Instrument.ACCORDION, Instrument.ACOUSTIC_BASS, Instrument.ACOUSTIC_GRAND_PIANO, Instrument.AGOGO_BELLS, Instrument.APPLAUSE, Instrument.BAGPIPE, Instrument.BANJO, Instrument.BASSOON, Instrument.BRASS_SECTION, Instrument.CELLO, Instrument.CHURCH_ORGAN, Instrument.CLARINET, Instrument.DISTORTION_GUITAR, Instrument.ELECTRIC_BASS_FINGER, Instrument.FX_1_RAIN, Instrument.FX_8_SCI_FI }; for (int i = 0; i < instruments.length; i++) { ParameterList parameters = new ParameterList(instruments[i]); int actualChannel = (Integer) Reflection.invokeMethod(converter, "addInstrumentAndGetChannel", parameters); } ParameterList parameters = new ParameterList(Instrument.HARMONICA); try { Reflection.invokeMethodAndExpectException(ProjectToMidiConverter.class, converter, "addInstrumentAndGetChannel", parameters); fail("Should throw a MidiException"); } catch (Exception e) { assertTrue("Should just throw a MidiException", e.getCause().toString().contains("org.catrobat.musicdroid.note.midi.MidiException")); } } public void testConvertProjectAndWriteMidi() throws MidiException { assertTrue(MidiFileTestDataFactory.createAndWriteMidiFileWithDeleteOnSuccess()); } public void testConvertProject() throws MidiException { ProjectToMidiConverter converter = new ProjectToMidiConverter(); Project project = ProjectTestDataFactory.createProjectWithSemiComplexTracks(); ParameterList parameters = new ParameterList(project); MidiFile midi = (MidiFile) Reflection.invokeMethod(converter, "convertProject", parameters); assertMidi(project, midi); } private void assertMidi(Project project, MidiFile midi) { int tempoTrackCount = 1; int noteTrackCount = project.size(); int trackCount = tempoTrackCount + noteTrackCount; assertEquals(trackCount, midi.getTrackCount()); ArrayList<MidiTrack> tracks = midi.getTracks(); MidiTrack tempoTrack = tracks.get(0); assertTempoTrack(project, tempoTrack); for (int i = 1; i < tracks.size(); i++) { MidiTrack noteTrack = tracks.get(i); assertNoteTrack(project.getTrack(i - 1), noteTrack); } } private void assertTempoTrack(Project project, MidiTrack tempoTrack) { assertEquals(3, tempoTrack.getEventCount()); Iterator<MidiEvent> it = tempoTrack.getEvents().iterator(); Text text = (Text) it.next(); Tempo tempo = (Tempo) it.next(); assertEquals(ProjectToMidiConverter.MUSICDROID_MIDI_FILE_IDENTIFIER, text.getText()); assertEquals(project.getBeatsPerMinute(), (int) tempo.getBpm()); } private void assertNoteTrack(Track track, MidiTrack noteTrack1) { int noteEventCount = track.size(); int programChangeEventCount = 1; int eventCount = noteEventCount + programChangeEventCount; assertEquals(eventCount, noteTrack1.getEventCount()); Iterator<MidiEvent> it = noteTrack1.getEvents().iterator(); ProgramChange program = (ProgramChange) it.next(); assertEquals(track.getInstrument().getProgram(), program.getProgramNumber()); int i = 0; long lastTick = 0; while (it.hasNext()) { MidiEvent midiEvent = it.next(); long midiEventTick = midiEvent.getTick(); if (midiEventTick != lastTick) { i = 0; } NoteEvent noteEvent = track.getNoteEventsForTick(midiEventTick).get(i); i++; if (midiEvent instanceof NoteOn) { NoteOn noteOnEvent = (NoteOn) midiEvent; assertEquals(noteEvent.getNoteName().getMidi(), noteOnEvent.getNoteValue()); } else if (midiEvent instanceof NoteOff) { NoteOff noteOffEvent = (NoteOff) midiEvent; assertEquals(noteEvent.getNoteName().getMidi(), noteOffEvent.getNoteValue()); } else { fail(); } lastTick = midiEventTick; } } }