/* -*- c-basic-offset: 2; indent-tabs-mode: nil; -*- */ /* * FreeDots -- MusicXML to braille music transcription * * Copyright 2008-2010 Mario Lang All Rights Reserved. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as * published by the Free Software Foundation. * * This code 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 General Public License * for more details (a copy is included in the LICENSE.txt file that * accompanied this code). * * You should have received a copy of the GNU General Public License * along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * This file is maintained by Mario Lang <mlang@delysid.org>. */ package freedots.playback; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MetaMessage; /** Encodes object references inside {@link javax.sound.midi.MetaMessage} * instances. * This is used by {@link freedots.musicxml.MIDISequence} to * annotate MIDI sequences with references to the objects responsible * for individual MIDI messages. * * @author Mario Lang */ public final class MetaEventRelay implements javax.sound.midi.MetaEventListener { private int lastId = 0; private Map<String, Object> objects = new HashMap<String, Object>(); private List<PlaybackObserver> playbackObservers = new ArrayList<PlaybackObserver>(2); private static final int PROPRIETARY = 0X7F; /** * Create an instance of MetaEventRelay. * * @param target initial target to deliver events to */ public MetaEventRelay(final PlaybackObserver target) { addPlaybackObserver(target); } /** Add a callback object to the list of observers. * @param playbackObserver is the observer to notify upon object playback */ public void addPlaybackObserver(final PlaybackObserver playbackObserver) { playbackObservers.add(playbackObserver); } /** * Create a new MetaMessage which wraps a reference to the specified object. * @param object the object to return when the MetaMessage fires * @return the MetaMessage * @throws InvalidMidiDataException if the required MIDI message could not be * created. * @throws NullPointerException if parameter object is {@code null}. */ public MetaMessage createMetaMessage(Object object) throws InvalidMidiDataException { if (object != null) { final int id = ++lastId; final String key = Integer.toString(id); objects.put(key, object); MetaMessage metaMessage = new MetaMessage(); metaMessage.setMessage(PROPRIETARY, key.getBytes(), key.length()); return metaMessage; } throw new NullPointerException(); } /** * Implements the MetaEventListener interface. * * @param meta the MetaMessage to handle */ public void meta(MetaMessage meta) { if (meta.getType() == PROPRIETARY) { String key = new String(meta.getData()); if (objects.containsKey(key)) { Object object = objects.get(key); for (PlaybackObserver observer:playbackObservers) observer.objectPlaying(object); } } } }