Package org.jnode.driver.sound.speaker.pc

Source Code of org.jnode.driver.sound.speaker.pc.PCSpeakerDriver

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.driver.sound.speaker.pc;

import java.security.PrivilegedExceptionAction;

import javax.naming.NameNotFoundException;

import org.jnode.driver.Device;
import org.jnode.driver.Driver;
import org.jnode.driver.DriverException;
import org.jnode.driver.sound.speaker.Note;
import org.jnode.driver.sound.speaker.SpeakerAPI;
import org.jnode.naming.InitialNaming;
import org.jnode.system.resource.IOResource;
import org.jnode.system.resource.ResourceManager;
import org.jnode.system.resource.ResourceNotFreeException;
import org.jnode.system.resource.ResourceOwner;
import org.jnode.util.AccessControllerUtils;

/**
* A driver for the internal speaker of a IBM Compatable machine.
*
* @author Matt Paine
*/
public class PCSpeakerDriver extends Driver implements SpeakerAPI {

    // ********** constants **********//

    /** The port for the speaker * */
    public static final int SPEAKER_PORT = 0x61;

    /** The PIT Control Port * */
    public static final int CONTROL_PORT = 0x43;

    /** The PIT Channel 2 Port * */
    public static final int CHANNEL2_PORT = 0x42;

    /** The base frequency for the PIT * */
    public static final int BASE_FREQUENCY = 1193100;

    // ********** private variables **********//

    /** This holds the reference to the IOResource we need to manipulate. * */
    private IOResource speakIO;

    /** This holds the reference to the IOResource for the PIT * */
    private IOResource pitIO;

    // ********** Driver implementation **********//

    /** A routine that claims all the resources nessasary to run the PCSpeaker. * */
    public void startDevice() throws DriverException {
        try {
            final Device dev = getDevice();
            final ResourceManager rm = InitialNaming.lookup(ResourceManager.NAME);
            speakIO = claimPorts(rm, dev, SPEAKER_PORT, 1);
            pitIO = claimPorts(rm, dev, CHANNEL2_PORT, 2);
            getDevice().registerAPI(SpeakerAPI.class, this);
            // do a test beep during startup
            // beep();
        } catch (NameNotFoundException nnfex) {
            throw new DriverException(nnfex);
        } catch (ResourceNotFreeException rnfex) {
            throw new DriverException(rnfex);
        }
    }

    /** A routine that releases all the resources back to the operating system. * */
    public void stopDevice() throws DriverException {
        noSound();
        getDevice().unregisterAPI(SpeakerAPI.class);
        pitIO.release();
        speakIO.release();
    }

    // ********** Speaker implementation **********//

    public void beep() {
        // backup the port, and start the beep
        int oldPort = speakIO.inPortByte(SPEAKER_PORT);
        int newValue = oldPort | 0x03; // 0b0000_0011;
        speakIO.outPortByte(SPEAKER_PORT, newValue);

        // sleep for the duration of the beep
        try {
            Thread.sleep(125);
        } catch (InterruptedException iex) {
            //empty
        }

        // restore the speaker port
        speakIO.outPortByte(SPEAKER_PORT, oldPort);
    }

    public void playNote(Note n) {
        pitIO.outPortByte(CONTROL_PORT, 0xb6);
        playNote(n.getNote(), n.getLength());
    }

    public void playNote(Note[] n) {
        pitIO.outPortByte(CONTROL_PORT, 0xb6);
        for (int x = 0; x < n.length; x++)
            playNote(n[x].getNote(), n[x].getLength());
    }

    public void playNote(int frequency, int length) {
        int freq = (BASE_FREQUENCY / frequency);
        pitIO.outPortByte(CHANNEL2_PORT, (byte) (freq & 0xff));
        pitIO.outPortByte(CHANNEL2_PORT, (byte) (freq >> 8));

        // backup the port, and start the beep
        int oldPort = speakIO.inPortByte(SPEAKER_PORT);
        int newValue = oldPort | 0x03; // 0b0000_0011;
        speakIO.outPortByte(SPEAKER_PORT, newValue);

        // sleep for the duration of the beep
        try {
            Thread.sleep(length);
        } catch (InterruptedException iex) {
            //empty
        }

        // restore the speaker port
        speakIO.outPortByte(SPEAKER_PORT, oldPort);
    }

    public void noSound() {
        int val = speakIO.inPortByte(SPEAKER_PORT);
        speakIO.outPortByte(SPEAKER_PORT, val & 0xFC);
    }

    private IOResource claimPorts(final ResourceManager rm, final ResourceOwner owner,
            final int low, final int length) throws ResourceNotFreeException, DriverException {
        try {
            return AccessControllerUtils.doPrivileged(new PrivilegedExceptionAction<IOResource>() {
                public IOResource run() throws ResourceNotFreeException {
                    return rm.claimIOResource(owner, low, length);
                }
            });
        } catch (ResourceNotFreeException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new DriverException("Unknown exception", ex);
        }

    }
}
TOP

Related Classes of org.jnode.driver.sound.speaker.pc.PCSpeakerDriver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.