javauis/nokiasound/javasrc/com/nokia/mid/sound/Sound.java
branchRCL_3
changeset 83 26b2b12093af
parent 77 7cee158cb8cd
child 84 0553e2305d00
--- a/javauis/nokiasound/javasrc/com/nokia/mid/sound/Sound.java	Wed Sep 15 12:05:25 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,698 +0,0 @@
-/*
-* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:  Provides Sound API for playing tones and digitized audio.
-*
-*/
-
-
-package com.nokia.mid.sound;
-
-import com.nokia.mj.impl.rt.support.Finalizer;
-import java.util.Vector;
-import com.nokia.mj.impl.utils.Logger;
-import java.lang.Thread;
-
-/**
- * <p>
- * Provides simple Sound API for playing tones and digitized audio.
- * </p><p>
- * Since MIDP doesn't have any Sound API for games there is a need
- * for proprietary sound extension to support devices audio
- * capabilities. Every implementation has capability to produce tone
- * sounds (e.g. ringing tones), this is the minimum support. Currently
- * some products support or will support also digitized audio formats.
- * The Game sound API will support both buzzer and digitized audio.
- * Buzzer must be supported by all implementations. If implementation
- * doesn't have buzzer the buzzer tones are emulated.
- * </p>
- * Since implementations have different audio capabilities,
- * application can query which audio formats are supported by
- * implementation by calling {@link #getSupportedFormats()}.
- * <p>
- * All implementations need to support at least tone based sounds
- * (type FORMAT_TONE) via {@link #Sound(int freq, long duration)} and
- * {@link #init(int freq, long duration)}. In addition all implementations
- * must support Smart messaging ringingtone format (type FORMAT_TONE)
- * via {@link #Sound(byte[] data, int type)} and
- * {@link #init(byte[] data, int type) }.
- * <p>
- * Note that there is also work going on with Multimedia API that
- * is done in JCP as
- * <a href="http://www.jcp.org/jsr/detail/135.jsp">JSR 135</a>.
- * The standard Multimedia API
- * will replace the proprietary Game Sound API when it is ready. However
- * Sound API will be supported also later on but probably it will be
- * stated as deprecated.
- * </p>
- * @version 1.1
- * @see com.nokia.mid.ui.DeviceControl
- * @since 1.0
- */
-
-public class Sound
-{
-
-    /**
-     * Tone based format is used.
-     *
-     * init(int freq, int duration) puts sound into this format.
-     * @since 1.0
-     *
-     */
-    public static final int FORMAT_TONE = 1;
-
-    /**
-     * Content is in WAV format.
-     * @since 1.0
-     *
-     */
-    public static final int FORMAT_WAV = 5;
-
-    /**
-     * Sound is playing.
-     * @since 1.0
-     *
-     */
-    public static final int SOUND_PLAYING = 0;
-
-    /**
-     * Sound is stopped.
-     * @since 1.0
-     *
-     */
-    public static final int SOUND_STOPPED = 1;
-
-    /**
-     * Sound is uninitialized (released).
-     * @since 1.0
-     */
-    public static final int SOUND_UNINITIALIZED = 3;
-
-    /**
-     * Sound is reinitialising
-     */
-    private static final int SOUND_REINITIALISING = 4;
-
-    private static final int FORMAT_BEEP = 2;
-    private static final int NOT_SUPPORTED_ERROR = 3;
-
-    private static final int ERR_NOT_READY = -18;
-    private static final int ERR_ARGUMENT  = -6;
-
-    private int iHandle;
-
-    private Finalizer iFinalizer;
-    private int iCurrentType;
-    private int iState;
-    private int iGain = -1;
-
-    Vector iSoundListeners = new Vector();
-
-    private static Sound iPlayingSound;
-
-    static
-    {
-        com.nokia.mj.impl.rt.support.Jvm.loadSystemLibrary("javanokiasound");
-    }
-
-    /**
-     * Constructors initialize the Sound object so that it is ready for
-     * playback. This constructor is used for initializing Sound
-     * object based on byte array data. The data should contain the data
-     * presented in the data format specified by type parameter. The Sound
-     * class defines also generally supported types as constants.
-     * <p>
-     * All implementations need to support at least Nokia
-     * Smart Messaging, Over the Air (OTA) ringingtone format.
-     * The type of this format is FORMAT_TONE.
-     * <p>
-     * Note: some implementations can't throw exceptions about
-     * sound data being corrupted or illegal during construction.
-     * This will result that IllagalArgumentException is delayed until
-     * play(int loop) method is called. Applications thus need to except
-     * that IllegalArgumentException is thrown in this method or during
-     * play method call.
-     * <p>
-     * @throws java.lang.IllegalArgumentException if the data can not be
-     recognized to
-     * given type or the type is unsupported or unknown
-     * @throws java.lang.NullPointerException if the data is null
-     * @since 1.0
-     *
-     */
-    public Sound(byte[] data, int type)
-    {
-        Logger.LOG(Logger.EJavaUI, Logger.EInfo, "Sound Constructor");
-        iFinalizer = registerForFinalization();
-
-        iHandle = _create();
-
-        iState = SOUND_UNINITIALIZED;
-
-        init(data, type);
-    }
-
-    /**
-     * Constructors initialize the Sound object so that it is ready for
-     * playback. Sound is initialized as a simple tone based sound.
-     * <p>
-     * See method {@link #init(int freq, long duration)} for
-     * freq value descriptions. See also a note on exceptions semantics in
-     * {@link #init(int freq, long duration)}.
-     *
-     * @param freq a frequency value
-     * @param duration the duration of the tone in milliseconds
-     * @throws java.lang.IllegalArgumentException if parameter values are
-     * illegal, freq is not in given range or duration is negative or zero
-     * @since 1.0
-     */
-    public Sound(int freq, long duration)
-    {
-
-        iFinalizer = registerForFinalization();
-        iHandle = _create();
-
-        iState = SOUND_UNINITIALIZED;
-
-        init(freq, duration);
-    }
-
-    /**
-      * Called when this object is finalized, frees native resources
-      */
-
-    public Finalizer registerForFinalization()
-    {
-
-        return new Finalizer()
-        {
-            public void finalizeImpl()
-            {
-                doFinalize();
-            }
-        };
-    }
-
-    void doFinalize()
-    {
-
-        if (iFinalizer == null)
-        {
-            return;
-        }
-        iFinalizer = null;
-
-        if (iHandle > 0)
-        {
-            _dispose(iHandle);
-        }
-    }
-
-    /**
-     * Releases audio resources reserved by this object. After object
-     * is released it goes to uninitialized state. This method should
-     * be called when Sound object is not needed anymore.
-     * @since 1.0
-     */
-    public void release()
-    {
-        if ((iState != SOUND_UNINITIALIZED) &&
-                (iState != SOUND_REINITIALISING))
-        {
-            iState = SOUND_REINITIALISING;
-            soundStateChanged(SOUND_UNINITIALIZED);
-        }
-
-        _release(iHandle);
-
-        iState = SOUND_UNINITIALIZED;
-
-    }
-
-    /**
-     * Initializes Sound to play a simple beep.
-     * <p>
-     * Note: some implementations may not support the full frequency
-     * scale defined in table below. They will throw
-     * IllegalArgumentException instead for unsupported values. The
-     * exception may also be delayed
-     * until the play(int loop) method is called.
-     * <p>
-     * Following table describes some freq argument
-     * values:
-     * <pre>
-     * Description            Frequency
-     * Freq off               0
-     * Ring freq A0           220
-     * Ring freq B0b          233
-     * Ring freq B0           247
-     * Ring freq C0           262
-     * Ring freq D0b          277
-     * Ring freq D0           294
-     * Ring freq E0b          311
-     * Ring freq E0           330
-     * Ring freq F0           349
-     * Ring freq G0b          370
-     * Ring freq G0           392
-     * Ring freq A1b          416
-     * Ring freq A1           440
-     * Ring freq B1b          466
-     * Ring freq B1           494
-     * Ring freq C1           523
-     * Ring freq D1b          554
-     * Ring freq D1           587
-     * Ring freq E1b          622
-     * Ring freq E1           659
-     * Ring freq F1           698
-     * Ring freq G1b          740
-     * Ring freq G1           784
-     * Ring freq A2b          831
-     * Ring freq A2           880
-     * Ring freq B2b          932
-     * Ring freq B2           988
-     * Ring freq C2           1047
-     * Ring freq D2b          1109
-     * Ring freq D2           1175
-     * Ring freq E2b          1245
-     * Ring freq E2           1319
-     * Ring freq F2           1397
-     * Ring freq G2b          1480
-     * Ring freq G2           1568
-     * Ring freq A3b          1661
-     * Ring freq A3           1760
-     * Ring freq B3b          1865
-     * Ring freq B3           1976
-     * Ring freq C3           2093
-     * Ring freq D3b          2217
-     * Ring freq D3           2349
-     * Ring freq E3b          2489
-     * Ring freq E3           2637
-     * Ring freq F3           2794
-     * Ring freq G3b          2960
-     * Ring freq G3           3136
-     * Ring freq A4b          3322
-     * Ring freq A4           3520
-     * Ring freq B4b          3729
-     * Ring freq B4           3951
-     * Ring freq C4           4186
-     * Ring freq D4b          4434
-     * Ring freq D4           4698
-     * Ring freq E4b          4978
-     * Ring freq E4           5274
-     * Ring freq F4           5588
-     * Ring freq G4b          5920
-     * Ring freq G4           6272
-     * Ring freq A5b          6644
-     * Ring freq A5           7040
-     * Ring freq B5b          7458
-     * Ring freq B5           7902
-     * Ring freq C5           8372
-     * Ring freq D5b          8870
-     * Ring freq D5           9396
-     * Ring freq E5b          9956
-     * Ring freq E5           10548
-     * Ring freq F5           11176
-     * Ring freq G5b          11840
-     * Ring freq G5           12544
-     * Ring freq A6b          13288
-     *
-     * </pre>
-     *
-     * @param duration length of the beep in milliseconds
-     * @param freq frequency to be played
-     * @throws java.lang.IllegalArgumentException if parameter values are
-     * illegal, freq is not in given range or duration is negative or zero
-     * @since 1.0
-     */
-    public void init(int freq, long duration)
-    {
-        if (duration < 1 || duration > 10000000)
-        {
-            throw(new IllegalArgumentException(
-                      "Bad duration value, must be 1-10000000"));
-        }
-        if (freq < 0 || freq > 15000)
-        {
-            throw(new IllegalArgumentException(
-                      "Bad frequency value, must be 0-15000"));
-        }
-        // if the uninitialised event is sent from native side, it reaches
-        // listener too late in TCK test sound8004, thus we send the event
-        // already here
-        if ((iState != SOUND_UNINITIALIZED) &&
-                (iState != SOUND_REINITIALISING))
-        {
-            iState = SOUND_REINITIALISING;
-            soundStateChanged(SOUND_UNINITIALIZED);
-        } // end of if (iState != SOUND_UNINITIALIZED)
-
-        iCurrentType = FORMAT_BEEP;
-        int err = _init(iHandle, iCurrentType, null, freq, duration);
-        if (err == ERR_NOT_READY)
-        {
-            throw new RuntimeException(Integer.toString(err));
-        }
-        else if (err == ERR_ARGUMENT)
-        {
-            throw new IllegalArgumentException("Data is invalid");            
-        }
-        iState = SOUND_STOPPED;
-    }
-
-    /**
-     * Initializes Sound object based on byte
-     * array data. The data should contain the data presented in the data
-     * format specified by type parameter. The Sound class defines also
-     * generally supported types as constants.
-     * <p>
-     * All implementations need to support at least Nokia
-     * Smart Messaging, Over the Air (OTA) ringingtone format.
-     * The type of this format is FORMAT_TONE.
-     * <p>
-     * Note: some implementations can't throw exceptions about
-     * sound data being corrupted or illegal during this method call.
-     * This will result that IllagalArgumentException is delayed until
-     * play(int loop) method is called. Applications thus need to except
-     * that IllegalArgumentException is thrown in this method or during
-     * play method call.
-     * <p>
-     * @param data a byte array containing the data to be played
-     * @param type type of the audio
-     * @throws java.lang.IllegalArgumentException if the data can not be
-     recognized to
-     * given type or the type is unsupported or unknown
-     * @throws java.lang.NullPointerException if the data is null
-     * @since 1.0
-     */
-    public void init(byte[] data, int type)
-    {
-        if (!(type == FORMAT_WAV || type == FORMAT_TONE))
-        {
-            throw(new IllegalArgumentException("Type is not supported"));
-        }
-        if (data == null)
-        {
-            throw(new NullPointerException("Data is null"));
-        }
-
-        if ((iState != SOUND_UNINITIALIZED) &&
-                (iState != SOUND_REINITIALISING))
-        {
-            iState = SOUND_REINITIALISING;
-            soundStateChanged(SOUND_UNINITIALIZED);
-        } // end of if (iState != SOUND_UNINITIALIZED)
-
-        iCurrentType = type;
-        int err = _init(iHandle, iCurrentType, data, 0, 0);
-        if (err == ERR_NOT_READY || err == ERR_ARGUMENT )
-        {
-            throw new IllegalArgumentException("Data is invalid");
-        }
-
-        iState = SOUND_STOPPED;
-    }
-
-
-    /**
-     * Get the current state of the Sound object.
-     *
-     * @return current state, SOUND_PLAYING, SOUND_STOPPED or
-     SOUND_UNINITIALIZED
-     * @since 1.0
-     *
-     */
-    public int getState()
-    {
-        if (iState == SOUND_REINITIALISING)
-        {
-            return SOUND_UNINITIALIZED;
-        }
-
-        iState = _getState(iHandle);
-        switch (iState)
-        {
-        case(0):  // ENotReady
-        case(4):  // EInitialising
-            iState = SOUND_UNINITIALIZED;
-            break;
-        case(1):  // EReadyToPlay
-            iState = SOUND_STOPPED;
-            break;
-        case(2):  // EPlaying
-            iState = SOUND_PLAYING;
-            break;
-        default:
-        }
-        return iState;
-    }
-
-    /**
-     * This method is used for starting the playback from the beginning of a
-     * sound object. The loop parameter defined the loop count for playback.
-     * Argument zero (0) means continuos looping. For uninitialized sound the
-     * play method doesn't do anything and silently returns. For stopped and
-     * playing sounds the playback starts from beginning of the sound with new
-     * looping information.
-     * <p>
-     * This method will throw IllegalStateException if playback cannot be
-     * started since all channels are in use, or playback is not possible
-     * because there is more higher priority system sounds being played.
-     * <p>
-     * If Sound playback is possible this method will return immediately and
-     * thus will not block the calling thread during the playback. If any error
-     * that prevents the playback is encountered during the playback, the
-     * playback is silently stopped as if called to the stop method.
-     *
-     * @param number number of times audio is played. Value 0 plays audio in
-     * continous loop.
-     * @throws java.lang.IllegalStateException if the sound object cannot be
-     * played because all the channels are already in use.
-     * @throws java.lang.IllegalArgumentException if the loop value is negative,
-     * or if sound values/date is illegal or corrupted.
-     * @since 1.0
-     *
-     */
-    public void play(int loop) throws IllegalArgumentException
-    {
-        if (loop < 0)
-        {
-            throw(new IllegalArgumentException("Negative loop value"));
-        }
-        if (iState == SOUND_REINITIALISING)
-        {
-            return;
-        } // end of if (iState == SOUND_REINITIALISING)
-
-        if (iPlayingSound != null)
-        {
-            if (iPlayingSound.getState() == SOUND_PLAYING)
-            {
-                iPlayingSound.stop();
-            }
-        } // end of if (iPlayingSound != null)
-
-        int error = _play(iHandle, loop);
-        if ((error == NOT_SUPPORTED_ERROR))
-        {
-            throw(new IllegalArgumentException("Sound is not supported"));
-        }
-        iPlayingSound = this;
-    }
-
-    /**
-     *  The method will stop the sound playback, storing the current position.
-     *  For sound that has never been started (may be uninitialized), or is
-     *  currently being stopped the method call doesn't do anything and returns
-     *  silently.
-     *
-     *  Note that for tone based sounds it is not possible to resume from
-     *  position the sound was stopped at, to be specific, stop will reset
-     *  the position to the beginning of the sound.
-     *  @since 1.0
-     */
-    public void stop()
-    {
-        if (iState == SOUND_REINITIALISING)
-        {
-            return;
-        } // end of if (iState == SOUND_REINITIALISING)
-        _stop(iHandle);
-    }
-
-    /**
-     *  The method will continue the stopped sound object from the position it
-     *  was stopped to. For sound that has never been started (may be
-     *  uninitialized), or is currently being played the method call doesn't
-     *  do anything.
-     *  <p>
-     *  Note: For tone based sounds the resume starts the sound from the
-     *  beginning of the sound clip.
-     *  @since 1.0
-     *
-     */
-    public void resume()
-    {
-        if (iState == SOUND_REINITIALISING)
-        {
-            return;
-        } // end of if (iState == SOUND_REINITIALISING)
-        _resume(iHandle);
-    }
-
-    /**
-     * Sets the gain for the sound object. The gain is a value between
-     * 0 and 255. Implementation scales the gain value to the limits it
-     * supports. Notice that any gain value > 0 should result a gain
-     * value > 0. If the gain is smaller than this minimum value then
-     * gain is set to 0, if the gain greater than this maximum value
-     * then the gain is set to maximum value (255).
-     *
-     * @param gain gain value: 0 - 255
-     * @throws java.lang.IllegalArgumentException if the gain not 0 - 255
-     * @since 1.0
-     */
-    public void setGain(int gain)
-    {
-        if (iState == SOUND_REINITIALISING)
-        {
-            return;
-        } // end of if (iState == SOUND_REINITIALISING)
-        if (gain < 0)
-        {
-            gain = 0;
-        }
-        else if (gain > 255)
-        {
-            gain = 255;
-        }
-        iGain = gain;
-        _setVolume(iHandle, iGain);
-    }
-
-    /**
-     * Get the gain (or volume) of Sound object. The gain is a value
-     * between 0 and 255. System returns a scaled value based on the
-     * limits it supports. Notice that any system gain value > 0 should
-     * return a gain value > 0.
-     *
-     * @return gain value 0 - 255
-     * @since 1.0
-     *
-     */
-    public int getGain()
-    {
-        if (iGain == -1)
-        {
-            return _volume(iHandle);
-        }
-        // we have previously set gain
-        return iGain;
-    }
-
-    /**
-     * Returns number of concurrent sounds the device can play for
-     * specific audio type. Returns 1 if only one sound can be played
-     * at a time. Notice that most types use same channel resources.
-     * @return total number of available channels.
-     * @param type the media type
-     * @throws java.lang.IllegalArgumentException if the type is unsupported
-     * or unknown
-     * @since 1.0
-     */
-    public static int getConcurrentSoundCount(int type)
-    {
-        if ((type != FORMAT_TONE) && (type != FORMAT_WAV))
-        {
-            throw(new IllegalArgumentException("Type is not supported"));
-        }
-
-        return 1;
-    }
-
-    /**
-     *  Returns the supported audio formats as an int array.
-     *
-     *  @return an array containing supported audio formats as
-     *  int values (e.g. FORMAT_TONE, FORMAT_WAV),
-     *  or an empty array if no audio formats are supported.
-     *  @since 1.0
-     */
-    static public int[] getSupportedFormats()
-    {
-        return(new int[] { FORMAT_TONE, FORMAT_WAV });
-    }
-
-    /**
-     *  Registeres a listener for playback state notifications.
-     *  @see com.nokia.mid.sound.SoundListener
-     *  @param listener a listener that is notified when state
-     *  changes occur or null if listener is to be
-     *  removed.
-     *  @since 1.0
-     *
-     */
-    public void setSoundListener(SoundListener listener)
-    {
-        iSoundListeners.addElement(listener);
-    }
-
-    /**
-     * Callback method when sound state changes
-     *
-     */
-    public void soundStateChanged(final int event)
-    {
-        /*
-        for(int i = 0; i < iSoundListeners.size(); i++)
-        {
-          ((SoundListener)iSoundListeners.elementAt(i)).soundStateChanged(this, event);
-        }
-        */
-        //Notify SoundState Listeners in a separate thread, so that application doesn't
-        //block main thread
-        new Thread(new Runnable()
-        {
-            public void run()
-            {
-                notifySoundStateListeners(event);
-            }
-        }).start();
-    }
-
-    /**
-     * Notify Sound State Listeners
-     */
-    public synchronized void notifySoundStateListeners(int event)
-    {
-        for (int i = 0; i < iSoundListeners.size(); i++)
-        {
-            ((SoundListener)iSoundListeners.elementAt(i)).soundStateChanged(this, event);
-        }
-    }
-
-    private native void _dispose(int aHandle);
-    private native int _create();
-    private native int _init(int aHandle, int aType,
-                             byte[] aData,
-                             int aFrequency, long aDuration);
-    private native void _release(int aHandle);
-    private native int _play(int aHandle, int aLoop);
-    private native void _stop(int aHandle);
-    private native void _resume(int aHandle);
-    private native void _setVolume(int aHandle, int aVolume);
-    private native int _volume(int aHandle);
-    private native int _getState(int aHandle);
-
-} //End of Sound class
-