home *** CD-ROM | disk | FTP | other *** search
Java Source | 2000-09-28 | 6.4 KB | 191 lines | [TEXT/CWIE] |
- /*
- File: DJ.java
-
- Copyright: © Copyright 1999-2000 Apple Computer, Inc. All rights reserved.
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- ("Apple") in consideration of your agreement to the following terms, and your
- use, installation, modification or redistribution of this Apple software
- constitutes acceptance of these terms. If you do not agree with these terms,
- please do not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject
- to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
- copyrights in this original Apple software (the "Apple Software"), to use,
- reproduce, modify and redistribute the Apple Software, with or without
- modifications, in source and/or binary forms; provided that if you redistribute
- the Apple Software in its entirety and without modifications, you must retain
- this notice and the following text and disclaimers in all such redistributions of
- the Apple Software. Neither the name, trademarks, service marks or logos of
- Apple Computer, Inc. may be used to endorse or promote products derived from the
- Apple Software without specific prior written permission from Apple. Except as
- expressly stated in this notice, no other rights or licenses, express or implied,
- are granted by Apple herein, including but not limited to any patent rights that
- may be infringed by your derivative works or by other works in which the Apple
- Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Change History (most recent first):
-
- */
-
-
- package com.apple.jens.radio;
-
- import java.io.*;
-
-
- /** An abstract base class that generates MP3-format Buffers to be streamed by Transmitters.
- A DJ subclass might get the data from local MP3 files (like FileDJ)
- or by relaying a stream from a remote MP3 server.
- @see FileDJ
- */
-
- public abstract class DJ extends Thread {
-
- /** Creates a DJ thread but doesn't start it yet. */
- public DJ( ) {
- super("DJ");
- }
-
-
- /** Sets the DJ's Station -- this is done once, when the DJ is created. */
- public void setStation( Station station ) {
- fStation = station;
- setName(station.getName()+"'s DJ");
-
- int bufferCount = station.getProperties().getIntProperty(kPropBufferCount,kDefaultBufferCount);
- fBuffers = new Buffer[bufferCount];
- // The array elements start out null since no buffers have been read yet.
- }
-
-
- public Station getStation( ) {
- return fStation;
- }
-
-
- // BUFFER ACCESS:
-
-
- //FIX: A better design for this would be to implement a BufferIterator,
- // to spare clients from having to deal with numeric indices.
-
-
- /** Returns the buffer index for a Transmitter to start with */
- int getFirstBufferIndex( ) {
- // Start 'em halfway around the ring to minimize chances of collision:
- return (fCurBuf + fBuffers.length/2) % fBuffers.length;
- }
-
-
- /** Returns the nth buffer counting around the buffer ring
- (using modulo arithmetic to index into the ring array.)
- This method is for use by Transmitters (readers), <i>not</i> by
- DJ subclasses. It will block if the nth buffer is currently
- being written to by the DJ, thus preventing Transmitters from
- overtaking the DJ. */
- Buffer getFilledBuffer( int n ) throws InterruptedException {
- if( n < 0 ) throw new IllegalArgumentException(Integer.toString(n));
- n = n % fBuffers.length;
-
- synchronized(this) {
- // Block until the buffer's been created and is no longer in use by the DJ:
- while( n == fCurBuf || fBuffers[n]==null )
- this.wait(); // Wait for getNextFreeBuffer to notify
- }
-
- return fBuffers[n];
- }
-
-
- /** Returns the next available buffer for the DJ to write to.
- This method should be called only by the subclass's <code>spin</code> method. */
- protected Buffer getNextFreeBuffer( ) {
- synchronized(this) {
- ++fCurBuf;
- if( fCurBuf == fBuffers.length )
- fCurBuf = 0;
- this.notifyAll(); // wake up Transmitters blocked in getBuffer method
- }
-
- Buffer next = fBuffers[fCurBuf];
- if( next == null ) // Allocate buffers 1st time around
- next = fBuffers[fCurBuf] = new Buffer(fStation.getStationName()+"#"+fCurBuf);
- return next;
- }
-
-
- // RUN-LOOP:
-
-
- /** Should be overridden by the caller to spin some tunes and generate
- some Buffers via setCurrentBuffer. */
- protected abstract void spin( ) throws IOException, InterruptedException;
-
-
- /** The DJ thread's run loop.
- Don't call this directly -- the DJ's owner should call start instead.
- @see Station */
- public void run( ) {
- try{
- while(true) {
- spin();
- }
- }catch( IOException x ) {
- Radio.WARN(1,this,"Caught a fatal IOException, exiting...");
- x.printStackTrace(System.err);
- }catch( InterruptedException ix ) {
- LOG(1,"Interrupted! Exiting...");
- }
- //FIX: When this thread exits, all Transmitters must be shut down
- // or they will block forever...
- }
-
-
- protected void LOG( int level, String msg ) {
- Radio.LOG(level,getName(),msg);
- }
-
-
- // INSTANCE DATA:
-
-
- private Station fStation;
-
- /** The circular ring of buffers used by the DJ and Transmitters. */
- private Buffer[] fBuffers;
-
- /** The index into fBuffers of the buffer the DJ is currently writing to.
- The buffer with this index will never be handed out
- to Transmitters -- they'll block until fCurBuf is incremented. */
- private int fCurBuf = -1;
-
-
- // STATIC DATA:
-
-
- /** The default number of buffers, if not overridden in Defaults or station prop files. */
- public static final int kDefaultBufferCount = 6;
-
-
- // PROPERTIES:
-
-
- public static final String kPropBufferCount = "buffer-count";
-
- }
-