//////////////////////////////////////////////////////////////////////////////// // Copyright 2013 Michael Schmalle - Teoti Graphix, LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License // // Author: Michael Schmalle, Principal Architect // mschmalle at teotigraphix dot com //////////////////////////////////////////////////////////////////////////////// package com.teotigraphix.caustk.sound; import org.androidtransfuse.event.EventObserver; import com.teotigraphix.caustic.core.IMemento; import com.teotigraphix.caustk.controller.ICaustkController; import com.teotigraphix.caustk.controller.command.CommandContext; import com.teotigraphix.caustk.controller.command.CommandUtils; import com.teotigraphix.caustk.controller.command.UndoCommand; import com.teotigraphix.caustk.sound.CaustkSoundSource.OnSoundSourceClear; import com.teotigraphix.caustk.sound.CaustkSoundSource.OnSoundSourceToneAdd; import com.teotigraphix.caustk.sound.CaustkSoundSource.OnSoundSourceToneRemove; public class SoundMixer implements ICaustkSoundMixer { /** * sound_mixer/set_send [0] [1] [2] * <p> * param 0 - tone index * <p> * param 1 - type (reverb, delay, volume, low, mid, high) * <p> * param 2 - value */ public static final String COMMAND_SET_SEND = "sound_mixer/set_send"; private ICaustkController controller; private MixerPanel mixerPanel; private EffectsRack effectsRack; @Override public void pasteMasterChannel(IMemento memento) { mixerPanel.pasteMasterChannel(memento); } @Override public void pasteMixerChannel(IMachine machine, IMemento memento) { mixerPanel.pasteChannel(machine, memento); } @Override public void pasteEffectChannel(IMachine machine, IMemento memento) { effectsRack.pasteChannel(machine, memento); } @Override public void copyEffectChannel(IMachine machine, IMemento memento) { effectsRack.copyChannel(machine, memento); } @Override public IMixerPanel getMixerPanel() { return mixerPanel; } @Override public IEffectsRack getEffectsRack() { return effectsRack; } //-------------------------------------------------------------------------- // Public Property API //-------------------------------------------------------------------------- //---------------------------------- // Master //---------------------------------- float getMasterVolume() { return mixerPanel.getMasterVolume(); } void setMasterVolume(float value) { mixerPanel.setMasterVolume(value); } float getMasterBass() { return mixerPanel.getMasterBass(); } void setMasterBass(float value) { mixerPanel.setMasterBass(value); } float getMasterMid() { return mixerPanel.getMasterMid(); } void setMasterMid(float value) { mixerPanel.setMasterMid(value); } float getMasterHigh() { return mixerPanel.getMasterHigh(); } void setMasterHigh(float value) { mixerPanel.setMasterHigh(value); } //---------------------------------- // Sends //---------------------------------- float getDelaySend(int index) { return mixerPanel.getDelaySend(index); } void setDelaySend(int index, float value) { mixerPanel.setDelaySend(index, value); } float getReverbSend(int index) { return mixerPanel.getReverbSend(index); } void setReverbSend(int index, float value) { mixerPanel.setReverbSend(index, value); } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- public SoundMixer(ICaustkController controller) { this.controller = controller; createMixerPanel(); createEffectsPanel(); controller.getDispatcher().register(OnSoundSourceClear.class, resetObserver); controller.getDispatcher().register(OnSoundSourceToneAdd.class, addObserver); controller.getDispatcher().register(OnSoundSourceToneRemove.class, removeObserver); } private void createMixerPanel() { mixerPanel = (MixerPanel)controller.getFactory().createMixerPanel(); mixerPanel.setEngine(controller); mixerPanel.setDelay((IMixerDelay)controller.getFactory().createMixerEffect(mixerPanel, MixerEffectType.DELAY)); mixerPanel.setReverb((IMixerReverb)controller.getFactory().createMixerEffect(mixerPanel, MixerEffectType.REVERB)); } private void createEffectsPanel() { effectsRack = (EffectsRack)controller.getFactory().createEffectRack(); effectsRack.setEngine(controller); } //-------------------------------------------------------------------------- // Public Observer Impl //-------------------------------------------------------------------------- private EventObserver<OnSoundSourceClear> resetObserver = new EventObserver<OnSoundSourceClear>() { @Override public void trigger(OnSoundSourceClear object) { } }; private EventObserver<OnSoundSourceToneAdd> addObserver = new EventObserver<OnSoundSourceToneAdd>() { @Override public void trigger(OnSoundSourceToneAdd object) { // IMachine machine = object.getTone().getMachine(); // mixerPanel.addMachine(machine); // effectsRack.addMachine(machine); } }; private EventObserver<OnSoundSourceToneRemove> removeObserver = new EventObserver<OnSoundSourceToneRemove>() { @Override public void trigger(OnSoundSourceToneRemove object) { // IMachine machine = object.getTone().getMachine(); // mixerPanel.removeMachine(machine); // effectsRack.removeMachine(machine); } }; public static class SoundMixerSetMasterCommand extends UndoCommand { private VO last; @Override protected void doExecute() { VO current = new VO(getContext()); last = new VO(getContext().api(SoundMixerAPI.class), current); update(current); } @Override protected void undoExecute() { update(last); } private void update(VO vo) { if (vo.type.equals("volume")) getContext().api(SoundMixerAPI.class).setMasterVolume(vo.value); else if (vo.type.equals("bass")) getContext().api(SoundMixerAPI.class).setMasterBass(vo.value); else if (vo.type.equals("mid")) getContext().api(SoundMixerAPI.class).setMasterMid(vo.value); else if (vo.type.equals("high")) getContext().api(SoundMixerAPI.class).setMasterHigh(vo.value); } class VO { private String type; private float value; public VO(CommandContext context) { type = CommandUtils.getString(getContext(), 0); value = CommandUtils.getFloat(getContext(), 1); } public VO(SoundMixerAPI api, VO current) { type = current.type; if (type.equals("volume")) value = api.getMasterVolume(); else if (type.equals("bass")) value = api.getMasterBass(); else if (type.equals("mid")) value = api.getMasterMid(); else if (type.equals("high")) value = api.getMasterHigh(); } } } public static class SoundMixerSetSendCommand extends UndoCommand { private VO last; @Override protected void doExecute() { VO current = new VO(getContext()); last = new VO(getContext().api(SoundMixerAPI.class), current); update(current); } @Override protected void undoExecute() { update(last); } private void update(VO vo) { if (vo.type.equals("delay")) getContext().api(SoundMixerAPI.class).setDelaySend(vo.index, vo.value); else if (vo.type.equals("reverb")) getContext().api(SoundMixerAPI.class).setReverbSend(vo.index, vo.value); } class VO { private int index; private String type; private float value; public VO(CommandContext context) { index = CommandUtils.getInteger(getContext(), 0); type = CommandUtils.getString(getContext(), 1); value = CommandUtils.getFloat(getContext(), 2); } public VO(SoundMixerAPI api, VO current) { index = current.index; type = current.type; if (type.equals("delay")) value = api.getDelaySend(index); else if (type.equals("reverb")) value = api.getReverbSend(index); } } } }