Code example for LinkedBlockingQueue

Methods: put, size

0
        int byteCount = Math.min(a.length - bufpos, length);
        System.arraycopy(buffer, 0, a, bufpos, byteCount);
        bufpos = bufpos + byteCount;
 
        if (bufpos == a.length) {
            buffers.put(a);
            updateLatency(); 
            bufpos = 0;
            a = free.poll();
            if (a == null) {
                a = new byte[BUFFER_SIZE];
            } 
 
            if (byteCount < length) {
                System.arraycopy(buffer, byteCount, a, bufpos, length - byteCount);
                bufpos = length - byteCount;
            } 
        } 
        return false; 
    } 
 
    private void initAudioThread() throws InterruptedException 
    { 
        audioThread = new Thread(this, "XMMS2 Android Audio");
        playing = true;
        free.clear();
        while (free.remainingCapacity() > 0) {
            free.put(new byte[BUFFER_SIZE]);
        } 
        a = free.take();
        audioThread.start();
    } 
 
    public boolean setFormat(int format, int channels, int rate)
    { 
        int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
        if (channels == 2) {
            channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
        } 
 
        int formatConfig = AudioFormat.ENCODING_PCM_16BIT;
        if (format != 2) {
            return false; 
        } 
 
        this.rate = rate;
        this.channelConfig = channelConfig;
        this.formatConfig = formatConfig;
        this.bufferSize = AudioTrack.getMinBufferSize(rate, channelConfig, formatConfig) * 10;
 
        synchronized (lock) {
            if (audioTrack != null && audioTrack.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) {
 
                formatChanged.set(true);
                try { 
                    if (bufpos > 0) { // put the last of the bytes belonging to the song in the play queue
                        byte[] b = new byte[bufpos];
                        System.arraycopy(a, 0, b, 0, bufpos);
                        bufpos = 0;
                        buffers.put(b);
                        a = free.take();
                    } 
 
                    // wait for the audio thread to stop, it should since this is blocking any new buffers to come in 
                    lock.wait();
                } catch (InterruptedException ignored) {}
            } 
        } 
 
        return true; 
    } 
 
    public void adjustVolume(float left, float right)
    { 
        if (audioTrack != null && audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
            audioTrack.setStereoVolume(left, right);
        } 
    } 
 
    // Because the server doesn't tell "non-status API" output plugin if it's a pause, we'll listen to this here 
    // and stop the audiotrack in case of pause. 
    @Override 
    public void playbackStatusChanged(PlaybackStatus newStatus)
    { 
        if (newStatus == PlaybackStatus.PAUSED && audioTrack != null &&
            audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING && playing) {
 
            paused.set(true);
        } else if (newStatus == PlaybackStatus.PLAYING && audioTrack != null && playing) {
            paused.set(false);
            synchronized (lock) {
                lock.notify();
            } 
        } 
    } 
 
    @Override 
    public void run() 
    { 
        while (!audioThread.isInterrupted() && playing) {
            audioTrack = null;
            if (buffers.size() < 3) {
                synchronized (buffers) {
                    try { 
                        buffers.wait();
                    } catch (InterruptedException ignored) {}
                } 
            } 
 
            audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate,
                                       channelConfig, formatConfig,
                                       bufferSize, AudioTrack.MODE_STREAM);
 
            if (audioTrack.getState() == AudioTrack.STATE_INITIALIZED &&
                audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
                    Intent intent = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
                    intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioTrack.getAudioSessionId());
                    intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, "org.xmms2.server");
                    context.sendBroadcast(intent);
                } 
 
                audioTrack.play();
            } 
 
            try { 
                playLoop(); 
            } catch (InterruptedException ignored) {}
 
            if (audioTrack != null && audioTrack.getState() == AudioTrack.STATE_INITIALIZED &&
                audioTrack.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
                    Intent intent = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
                    intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioTrack.getAudioSessionId());
                    intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, "org.xmms2.server");
                    context.sendBroadcast(intent);
                } 
 
                audioTrack.stop();
            } 
 
            synchronized (lock) {
                lock.notify();
                formatChanged.set(false);
            } 
        } 
    } 
 
    private void playLoop() throws InterruptedException 
    { 
        while (audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING &&
               !audioThread.isInterrupted()) {
            byte b[] = null;
            while (b == null) {
                if (paused.get()) {
                    audioTrack.pause();
                    synchronized (lock) {
                        lock.wait();
                    } 
                    audioTrack.play();
                } 
                b = buffers.poll(20, TimeUnit.MILLISECONDS);
                if (b == null && formatChanged.get()) {
                    return; 
                } 
            } 
 
            updateLatency(); 
 
            if (audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
                audioTrack.write(b, 0, b.length);
            } 
            if (b.length == BUFFER_SIZE) {
                free.offer(b);
            } 
        } 
    } 
 
    // TODO inaccurate 
    private void updateLatency() 
    { 
        latency = buffers.size() * BUFFER_SIZE + bufpos;
    } 
 
}