Source.java

/**
 * Copyright (c) 2012 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.
 * See LICENSE.TXT for license information.
 */

package com.nokia.midp.examples.jsr234.mansion;

import javax.microedition.lcdui.Graphics;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
import java.io.InputStream;
import java.io.IOException;
import javax.microedition.amms.control.audio3d.LocationControl;
import javax.microedition.amms.*;

import java.util.Random;
import javax.microedition.lcdui.Canvas;

/**
 * Sound source with graphics, too
 */
public class Source implements Runnable {

    final static int BALL_RADIUS = 5;
    final static int BALL_DIAM = BALL_RADIUS * 2;
    private int x = 0, y = 0; //sound source's location
    private Player player;
    private VolumeControl volC;
    private LocationControl locC;
    private SoundSource3D ss3D;
    /** keeps the mover thread active until true*/
    protected boolean closed = false;
    // needed for collision detection in random movements:
    House house = null;
    Canvas canvas = null; // for repaint after movement
    static Random random = new Random();
    private final int color;

    public Source(int x, int y, String fileName, House house, Canvas canvas, int color) {
        this.x = x;
        this.y = y;
        this.house = house;
        this.canvas = canvas;
        this.color = color;

        InputStream is = getClass().getResourceAsStream(fileName);
        if (is == null) {
            throw new IllegalArgumentException("error creating InputStream of" + fileName);
        }
        try {
            player = Manager.createPlayer(is, "audio/X-wav");
            if (player == null) {
                throw new IllegalArgumentException("error creating Player of" + fileName);
            }
            player.realize();
            player.setLoopCount(-1); //indefinetely
        } catch (IOException e) {
            System.out.println(e);
        } catch (MediaException e) {
            System.out.println(e);
        }
        volC = (VolumeControl) player.getControl("VolumeControl");
        if (volC != null) {
            volC.setLevel(100);
        }

        try {
            ss3D = GlobalManager.createSoundSource3D();
            if (ss3D != null) {
                ss3D.addPlayer(player);
                locC = (LocationControl) ss3D.getControl("javax.microedition.amms.control.audio3d.LocationControl");
                if (locC != null) {
                    locC.setCartesian(x, 0, y);
                } else {
                    //LocationControl not available
                    ss3D.removePlayer(player);
                }
                player.prefetch();
            }
        } catch (MediaException e) {
            System.out.println(e);
        }
    }

    /**
     * Deinits players
     */
    protected void destroy() {
        closed = true;
        if (player != null) {
            player.close();
        }
    }

    public final void start() {
        try {
            player.start();
        } catch (MediaException e) {
            System.out.println(e);
        } catch (IllegalStateException ise) {
            //synchronization problems with close.
        }
    }

    public final void stop() {
        if (player.getState() == Player.STARTED) {
            Thread t = new Thread() {

                public void run() {
                    try {
                        player.stop();
                    } catch (MediaException e) {
                        System.out.println(e);
                    } catch (IllegalStateException ise) {
                        //synchronization problems with close.
                    }
                }
            };
            t.start();
        }
    }

    public final void setLocation(int x, int y) {
        this.x = x;
        this.y = y;
        if (locC != null) {
            locC.setCartesian(x, 0, y);
        }
    }

    public final int getX() {
        return x;
    }

    public void run() {
        int tempX = 0;
        int tempY = 0;
        while (!closed) {
            tempX = x + (random.nextInt() & 256) - 128;
            tempY = y + (random.nextInt() & 256) - 128;
            if (house.isInside(tempX, tempY)) {
                setLocation(tempX, tempY);
                canvas.repaint();
            }
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
            }
        }
    }

    /**
     * Draws the sound source to given Graphics.
     * @param dx x translation in millipixels
     * @param dy y translation in millipixels
     * @param rot rotation in deci-angles
     */
    public void draw(Graphics g, int dx, int dy, int rot) {
        int newX = Trig.transXS(x - dx, y - dy, rot);
        int newY = Trig.transYS(x - dx, y - dy, rot);
        drawDot(g, newX, newY);
    }

    /**
     * Draws a dot to given graphics
     */
    void drawDot(Graphics g, int x, int y) {
        g.setColor(color);
        g.fillArc(x - BALL_RADIUS, y - BALL_RADIUS, BALL_DIAM, BALL_DIAM, 0, 360);
    }
}