001package jmri.implementation;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import jmri.*;
007import jmri.jmrit.audio.AudioSource;
008
009/**
010 * Base implementation of the Audio class.
011 * <p>
012 * Specific implementations will extend this base class.
013 *
014 * @author Matthew Harris copyright (c) 2009
015 */
016public abstract class AbstractAudio extends AbstractNamedBean implements Audio {
017
018    private int _state = STATE_INITIAL;
019
020    private static final int INT_PRECISION = (int) Math.pow(10, DECIMAL_PLACES);
021
022    /**
023     * Abstract constructor for new Audio with system name
024     *
025     * @param systemName Audio object system name (e.g. IAS1, IAB4)
026     */
027    public AbstractAudio(String systemName) {
028        super(systemName);
029    }
030
031    /**
032     * Abstract constructor for new Audio with system name and user name
033     *
034     * @param systemName Audio object system name (e.g. IAS1, IAB4)
035     * @param userName   Audio object user name
036     */
037    public AbstractAudio(String systemName, String userName) {
038        super(systemName, userName);
039    }
040
041    @Override
042    public int getState() {
043        return this._state;
044    }
045
046    @Override
047    public void setState(int newState) {
048        Object _old = this._state;
049        this._state = newState;
050        stateChanged((Integer) _old);
051        firePropertyChange("State", _old, _state); // NOI18N
052    }
053
054    /**
055     * Abstract method that concrete classes will implement to perform necessary
056     * cleanup routines.
057     * <p>
058     * This method is now included in dispose(). The caller can
059     * call dispose() to cleanup and deregister an audio object.
060     */
061    abstract protected void cleanup();
062
063    @Override
064    public void dispose() {
065        InstanceManager.getDefault(jmri.AudioManager.class).deregister(this);
066        cleanup();
067        super.dispose();
068    }
069
070    /**
071     * Static method to round a float value to the specified number of decimal
072     * places
073     *
074     * @param value  float value to round
075     * @param places number of decimal places to round to
076     * @return float value rounded to specified number of decimal places
077     */
078    public static float roundDecimal(float value, double places) {
079        double multiplier = Math.pow(10, places);
080        value *= multiplier;
081        return (float) (Math.round(value) / multiplier);
082    }
083
084    /**
085     * Static method to round a float value to the number of decimal places
086     * defined by DECIMAL_PLACES.
087     *
088     * @param value float value to round
089     * @return float value rounded to DECIMAL_PLACES decimal places
090     */
091    public static float roundDecimal(float value) {
092        return roundDecimal(value, Math.log10(INT_PRECISION));
093    }
094
095    @Override
096    public String getBeanType() {
097        return Bundle.getMessage("BeanNameAudio");
098    }
099
100    /** {@inheritDoc} */
101    @Override
102    public List<NamedBeanUsageReport> getUsageReport(NamedBean bean) {
103        List<NamedBeanUsageReport> report = new ArrayList<>();
104        if (bean != null) {
105            if (this instanceof AudioSource) {
106                var source = (AudioSource) this;
107                if (bean.equals(source.getAssignedBuffer())) {
108                    report.add(new NamedBeanUsageReport("AudioBuffer"));  // NOI18N
109                }
110            }
111        }
112        return report;
113    }
114}