001package jmri.jmrit.audio;
002
003import com.jogamp.openal.AL;
004import com.jogamp.openal.ALExtConstants;
005import javax.vecmath.Vector3f;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * JOAL implementation of the Audio Listener sub-class.
011 * <p>
012 * For now, no system-specific implementations are forseen - this will remain
013 * internal-only
014 * <br><br><hr><br><b>
015 * This software is based on or using the JOAL Library available from
016 * <a href="http://jogamp.org/joal/www/">http://jogamp.org/joal/www/</a>
017 * </b><br><br>
018 * JOAL is released under the BSD license. The full license terms follow:
019 * <br><i>
020 * Copyright (c) 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
021 * <br>
022 * Redistribution and use in source and binary forms, with or without
023 * modification, are permitted provided that the following conditions are
024 * met:
025 * <br>
026 * - Redistribution of source code must retain the above copyright
027 *   notice, this list of conditions and the following disclaimer.
028 * <br>
029 * - Redistribution in binary form must reproduce the above copyright
030 *   notice, this list of conditions and the following disclaimer in the
031 *   documentation and/or other materials provided with the distribution.
032 * <br>
033 * Neither the name of Sun Microsystems, Inc. or the names of
034 * contributors may be used to endorse or promote products derived from
035 * this software without specific prior written permission.
036 * <br>
037 * This software is provided "AS IS," without a warranty of any kind. ALL
038 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
039 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
040 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
041 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
042 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
043 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
044 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
045 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
046 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
047 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
048 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
049 * <br>
050 * You acknowledge that this software is not designed or intended for use
051 * in the design, construction, operation or maintenance of any nuclear
052 * facility.
053 * <br><br><br></i>
054 * <hr>
055 * This file is part of JMRI.
056 * <p>
057 * JMRI is free software; you can redistribute it and/or modify it under the
058 * terms of version 2 of the GNU General Public License as published by the Free
059 * Software Foundation. See the "COPYING" file for a copy of this license.
060 * <p>
061 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
062 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
063 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
064 *
065 * @author Matthew Harris copyright (c) 2009
066 */
067public class JoalAudioListener extends AbstractAudioListener {
068
069    private static AL al = JoalAudioFactory.getAL();
070
071    private boolean initialised = false;
072
073    /**
074     * Constructor for new JoalAudioListener with system name
075     *
076     * @param systemName AudioListener object system name (e.g. IAL)
077     */
078    public JoalAudioListener(String systemName) {
079        super(systemName);
080        if (log.isDebugEnabled()) {
081            log.debug("New JoalAudioListener: {}", systemName);
082        }
083        initialised = init();
084    }
085
086    /**
087     * Constructor for new JoalAudioListener with system name and user name
088     *
089     * @param systemName AudioListener object system name (e.g. IAL)
090     * @param userName   AudioListener object user name
091     */
092    public JoalAudioListener(String systemName, String userName) {
093        super(systemName, userName);
094        if (log.isDebugEnabled()) {
095            log.debug("New JoalAudioListener: {} ({})", userName, systemName);
096        }
097        initialised = init();
098    }
099
100    private boolean init() {
101        // Nothing to do for the listener
102        return true;
103    }
104
105    @Override
106    protected void changePosition(Vector3f pos) {
107        if (initialised) {
108            al.alListener3f(AL.AL_POSITION, pos.x, pos.y, pos.z);
109            if (JoalAudioFactory.checkALError()) {
110                log.warn("Error updating position of JoalAudioListener ({})", this.getSystemName());
111            }
112        }
113    }
114
115    @Override
116    public void setVelocity(Vector3f vel) {
117        super.setVelocity(vel);
118        if (initialised) {
119            al.alListener3f(AL.AL_VELOCITY, vel.x, vel.y, vel.z);
120            if (JoalAudioFactory.checkALError()) {
121                log.warn("Error updating velocity setting of JoalAudioListener ({})", this.getSystemName());
122            }
123        }
124    }
125
126    @Override
127    public void setOrientation(Vector3f at, Vector3f up) {
128        super.setOrientation(at, up);
129        if (initialised) {
130            al.alListenerfv(AL.AL_ORIENTATION,
131                    new float[]{at.x, at.y, at.z,
132                        up.x, up.y, up.z},
133                    0);
134            if (JoalAudioFactory.checkALError()) {
135                log.warn("Error updating orientation of JoalAudioListener ({})", this.getSystemName());
136            }
137        }
138    }
139
140    @Override
141    public void setGain(float gain) {
142        super.setGain(gain);
143        if (initialised) {
144            al.alListenerf(AL.AL_GAIN, gain);
145            if (JoalAudioFactory.checkALError()) {
146                log.warn("Error updating gain setting of JoalAudioListener ({})", this.getSystemName());
147            }
148        }
149    }
150
151    @Override
152    public void setMetersPerUnit(float metersPerUnit) {
153        super.setMetersPerUnit(metersPerUnit);
154        if (initialised) {
155            al.alListenerf(ALExtConstants.AL_METERS_PER_UNIT, metersPerUnit);
156            if (JoalAudioFactory.checkALError()) {
157                log.warn("Error updating meters per unit setting of JoalAudioListener ({})", this.getSystemName());
158            }
159        }
160    }
161
162    @Override
163    public void stateChanged(int oldState) {
164        super.stateChanged(oldState);
165        if (initialised) {
166            al.alListenerf(AL.AL_GAIN, this.getGain());
167            al.alListener3f(AL.AL_POSITION, this.getCurrentPosition().x, this.getCurrentPosition().y, this.getCurrentPosition().z);
168            al.alListener3f(AL.AL_VELOCITY, this.getVelocity().x, this.getVelocity().y, this.getVelocity().z);
169            al.alListenerfv(AL.AL_ORIENTATION,
170                    new float[]{this.getOrientation(AT).x, this.getOrientation(AT).y, this.getOrientation(AT).z,
171                        this.getOrientation(UP).x, this.getOrientation(UP).y, this.getOrientation(UP).z},
172                    0);
173            if (JoalAudioFactory.checkALError()) {
174                log.warn("Error updating JoalAudioListener ({})", this.getSystemName());
175            }
176        } else {
177            initialised = init();
178        }
179    }
180
181    @Override
182    protected void cleanup() {
183        // no clean-up needed for Listener
184        if (log.isDebugEnabled()) {
185            log.debug("Cleanup JoalAudioListener ({})", this.getSystemName());
186        }
187    }
188
189    private static final Logger log = LoggerFactory.getLogger(JoalAudioListener.class);
190
191}