Tuner.java

/**
 * Copyright (c) 2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 */

package com.nokia.example.ammstuner;

import java.io.IOException;

import javax.microedition.amms.control.tuner.TunerControl;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;

/**
 * The class for managing the tuner.
 */
public class Tuner {
    // Constants
    public static final int MIN_FREQUENCY = 875000;
    public static final int MAX_FREQUENCY = 1080000;

    // Members
    private Listener listener;
    private Thread thread;
    private TunerControl tunerControl;
    private Player radioPlayer;
    private int frequency;
    private boolean isStarted;

    /**
     * Constructor.
     * @param ammsTuner
     */
    public Tuner(Listener listener) {
        this.listener = listener;
        isStarted = false;
    }

    /** 
     * @return The current frequency.
     */
    public int getCurrentFrequency() {
        return frequency;
    }

    /** 
     * @return The current frequency of the tuner control or 0 if not available.
     */
    public int getTunerControlFrequency() {
        if (radioPlayer != null) {
            return tunerControl.getFrequency();
        }
        
        return 0;
    }

    /** 
     * @return True if the radio has been started. False otherwise.
     */
    public boolean getIsStarted() {
        return isStarted;
    }

    /**
     * Initializes the radio.
     */    
    public void initializeRadio () {
        thread = new Thread() {
            public void run() {
                try {
                    radioPlayer = Manager.createPlayer("capture://radio");
                    radioPlayer.realize();
                    tunerControl = (TunerControl)radioPlayer.getControl(
                        "javax.microedition.amms.control.tuner.TunerControl");
                    tunerControl.setStereoMode(TunerControl.STEREO);
                }
                catch (MediaException me) {
                    if (listener != null) {
                        listener.onError("Tuner.initializeRadio(): " + me.toString());
                    }
                }
                catch (IOException ioe) {
                    if (listener != null) {
                        listener.onError("Tuner.initializeRadio(): " + ioe.toString());
                    }
                }
                
                if (listener != null) {
                    listener.onInitialized();
                }
            }
        };
        
        thread.start();
    }

    /**
     * Starts the radio.
     */     
    public void startRadio() {
        thread = new Thread() {
            public void run() {
                try {
                    radioPlayer.start();
                    
                    if (listener != null) {
                        isStarted = true;
                        listener.onStarted();
                    }
                    
                    frequency = tunerControl.seek(MIN_FREQUENCY, TunerControl.MODULATION_FM, true);
                    
                    if (frequency == 0) {
                        if (listener != null) {
                            listener.onSeekFailed();
                        }
                    }
                    else {
                        if (listener != null) {
                            listener.onFrequencyChanged(frequency);
                        }
                    }
                }
                catch (MediaException me) {
                    if (listener != null) {
                        listener.onError("Tuner.startRadio(): " + me.toString());
                    }
                }
                catch (IllegalArgumentException iae) {
                    if (listener != null) {
                    	listener.onError("Tuner.startRadio(): " + iae.toString());
                    }
                }
            }
        };
        
        thread.start();
    }

    /**
     * Seeks for a new frequency, either up or down from the current frequency.
     * @param currentFrequency The current frequency
     * @param up If true, method seeks upwards, if false, seeks downwards.
     * @return True if successful, false otherwise.
     */
    public boolean seekNextFrequency(final int currentFrequency, boolean up) {
        if (radioPlayer == null) {
            return false;
        }
        
        final boolean upwards = up;
        
        thread = new Thread() {
            public void run() {
                try {
                    frequency = tunerControl.seek(currentFrequency, TunerControl.MODULATION_FM, upwards);
                    
                    if (frequency == 0) {
                        if (listener != null) {
                            listener.onSeekFailed();
                        }
                    }
                    else {
                        if (listener != null) {
                            listener.onFrequencyChanged(frequency);
                        }
                    }
                }
                catch (MediaException me) {
                    if (listener != null) {
                    	listener.onError("Tuner.seekNextFrequency(): " + me.toString());
                    }
                }
            }
        };
        
        thread.start();
        return true;
    }

    /**
     * Stops the radio player.
     */
    public void stopRadio() {
        if (radioPlayer == null) {
            return;
        }
        
        try {
            radioPlayer.stop();
        }
        catch (MediaException me) {
            if (listener != null) {
            	listener.onError("Tuner.stopRadio(): " + me.toString());
            }
        }
        
        if (listener != null) {
            isStarted = false;
            listener.onStopped();
        }
    }

    /**
     * Stops and closes the radio player.
     */
    public void killRadio() {
        if (radioPlayer == null) {
            return;
        }
        
        try {
            radioPlayer.stop();
            radioPlayer.close();
            radioPlayer = null;
            
            if (thread != null) {
                thread = null;
            }
        }
        catch (MediaException me) {
            if (listener != null) {
            	listener.onError("Tuner.killRadio(): " + me.toString());
            }
        }
        
        if (listener != null) {
        	isStarted = false;
            listener.onStopped();
        }
    }

    /**
     * A listener interface for the UI. The listener gets notified about the
     * changes in the state of the tuner. 
     */
    public interface Listener {
        void onInitialized();
        void onStarted();
        void onStopped();
        void onFrequencyChanged(int frequency);
        void onSeekFailed();
        void onError(String errorMessage);
    }
}