uk.co.modularaudio.mads.base.imixern.ui.MixerNMadUiInstance.java Source code

Java tutorial

Introduction

Here is the source code for uk.co.modularaudio.mads.base.imixern.ui.MixerNMadUiInstance.java

Source

/**
 *
 * Copyright (C) 2015 - Daniel Hams, Modular Audio Limited
 *                      daniel.hams@gmail.com
 *
 * Mad is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Mad 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with Mad.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package uk.co.modularaudio.mads.base.imixern.ui;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import uk.co.modularaudio.mads.base.imixern.mu.MixerNIOQueueBridge;
import uk.co.modularaudio.mads.base.imixern.mu.MixerNMadDefinition;
import uk.co.modularaudio.mads.base.imixern.mu.MixerNMadInstance;
import uk.co.modularaudio.mads.base.imixern.ui.lane.MeterValueReceiver;
import uk.co.modularaudio.util.audio.gui.mad.MadUiDefinition;
import uk.co.modularaudio.util.audio.gui.mad.helper.AbstractNoNameChangeNonConfigurableMadUiInstance;
import uk.co.modularaudio.util.audio.mad.hardwareio.HardwareIOChannelSettings;
import uk.co.modularaudio.util.audio.mad.ioqueue.IOQueueEvent;
import uk.co.modularaudio.util.audio.mad.ioqueue.ThreadSpecificTemporaryEventStorage;
import uk.co.modularaudio.util.audio.mad.timing.MadFrameTimeFactory;
import uk.co.modularaudio.util.audio.mad.timing.MadTimingParameters;
import uk.co.modularaudio.util.math.Float16;
import uk.co.modularaudio.util.table.Span;

public class MixerNMadUiInstance<D extends MixerNMadDefinition<D, I>, I extends MixerNMadInstance<D, I>>
        extends AbstractNoNameChangeNonConfigurableMadUiInstance<D, I> {
    private static Log log = LogFactory.getLog(MixerNMadUiInstance.class.getName());

    private final MeterValueReceiver[] laneMeterReceiversMap;

    public MixerNMadUiInstance(final Span span, final I instance,
            final MadUiDefinition<D, I> componentUiDefinition) {
        super(span, instance, componentUiDefinition);

        laneMeterReceiversMap = new MeterValueReceiver[instance.getDefinition().getMixerInstanceConfiguration()
                .getNumTotalLanes()];
    }

    @Override
    public void receiveStartup(final HardwareIOChannelSettings ratesAndLatency,
            final MadTimingParameters timingParameters, final MadFrameTimeFactory frameTimeFactory) {
        super.receiveStartup(ratesAndLatency, timingParameters, frameTimeFactory);

        // Use the sample rate (i.e. one second between peak reset)
        final int framesBetweenPeakReset = ratesAndLatency.getAudioChannelSetting().getDataRate().getValue();

        for (final MeterValueReceiver mvr : laneMeterReceiversMap) {
            mvr.setFramesBetweenPeakReset(framesBetweenPeakReset);
        }
    }

    @Override
    public void doDisplayProcessing(final ThreadSpecificTemporaryEventStorage guiEventStorage,
            final MadTimingParameters timingParameters, final long currentGuiTime) {
        // Consume any incoming messages from the instance before we pass the tick onto any children
        localQueueBridge.receiveQueuedEventsToUi(guiEventStorage, instance, this);
        //      log.debug("Consumed " + numMessagesConsumed + " messages");
        //      debugTimestamp( "UI Mixer", currentGuiTime );

        super.doDisplayProcessing(guiEventStorage, timingParameters, currentGuiTime);
    }

    @Override
    public void consumeQueueEntry(final I instance, final IOQueueEvent nextOutgoingEntry) {
        switch (nextOutgoingEntry.command) {
        case MixerNIOQueueBridge.COMMAND_OUT_METER: {
            // lane number, left + right amps as float16 values
            final long value = nextOutgoingEntry.value;
            final int laneNum = (int) (value & 0xFFFFFFFF);
            final int leftChannelF16 = (int) ((value >> 48) & 0xFFFF);
            final int rightChannelF16 = (int) ((value >> 32) & 0xFFFF);

            final float leftChannelAmp = Float16.fromInt(leftChannelF16);
            final float rightChannelAmp = Float16.fromInt(rightChannelF16);

            //            log.debug("Consuming one for lane " + laneNum );

            laneMeterReceiversMap[laneNum].receiveMeterReadingLevel(nextOutgoingEntry.frameTime, leftChannelAmp,
                    rightChannelAmp);

            break;
        }
        case MixerNIOQueueBridge.COMMAND_IN_LANE_AMP:
        case MixerNIOQueueBridge.COMMAND_IN_LANE_MUTE:
        case MixerNIOQueueBridge.COMMAND_IN_LANE_PAN:
        case MixerNIOQueueBridge.COMMAND_IN_LANE_SOLO: {
            // Ignore them.
            break;
        }
        default: {
            if (log.isErrorEnabled()) {
                log.error("Unknown outgoing command: " + nextOutgoingEntry.command);
            }
            break;
        }
        }
    }

    public void registerLaneMeterReceiver(final int laneNum, final MeterValueReceiver meterReceiver) {
        laneMeterReceiversMap[laneNum] = meterReceiver;
    }

    public void sendLaneMute(final int laneNumber, final boolean muteValue) {
        final long muteBits = (muteValue ? 1 : 0);
        final long joinedParts = (muteBits << 32) | laneNumber;
        sendTemporalValueToInstance(MixerNIOQueueBridge.COMMAND_IN_LANE_MUTE, joinedParts);
    }

    public void sendSoloValue(final int laneNumber, final boolean soloValue) {
        final long soloBits = (soloValue ? 1 : 0);
        final long joinedParts = (soloBits << 32) | laneNumber;
        sendTemporalValueToInstance(MixerNIOQueueBridge.COMMAND_IN_LANE_SOLO, joinedParts);
    }

    public void sendLaneAmp(final int laneNumber, final float newValue) {
        final long floatIntBits = Float.floatToIntBits(newValue);
        final long joinedParts = (floatIntBits << 32) | laneNumber;
        sendTemporalValueToInstance(MixerNIOQueueBridge.COMMAND_IN_LANE_AMP, joinedParts);
    }

    public void sendUiActive(final boolean active) {
        sendCommandValueToInstance(MixerNIOQueueBridge.COMMAND_IN_ACTIVE, (active ? 1 : 0));
        if (active) {
            // Reset meters to zero so they start as intended
            for (final MeterValueReceiver mvr : laneMeterReceiversMap) {
                mvr.receiveMeterReadingLevel(0, 0.0f, 0.0f);
            }
        }
    }

    public void sendLanePan(final int laneNumber, final float panValue) {
        final long floatIntBits = Float.floatToIntBits(panValue);
        final long joinedParts = (floatIntBits << 32) | laneNumber;
        sendTemporalValueToInstance(MixerNIOQueueBridge.COMMAND_IN_LANE_PAN, joinedParts);
    }
}