< prev index next >

src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */

  25 package com.sun.media.sound;
  26 
  27 import javax.sound.sampled.AudioFormat;
  28 import javax.sound.sampled.AudioInputStream;
  29 import java.io.EOFException;
  30 import java.io.IOException;
  31 import java.io.InputStream;
  32 



  33 /**
  34  * A jitter corrector to be used with SoftAudioPusher.
  35  *
  36  * @author Karl Helgason
  37  */
  38 public final class SoftJitterCorrector extends AudioInputStream {
  39 
  40     private static class JitterStream extends InputStream {
  41 
  42         static int MAX_BUFFER_SIZE = 1048576;
  43         boolean active = true;
  44         Thread thread;
  45         AudioInputStream stream;
  46         // Cyclic buffer
  47         int writepos = 0;
  48         int readpos = 0;
  49         byte[][] buffers;
  50         private final Object buffers_mutex = new Object();
  51 
  52         // Adapative Drift Statistics


 107                     int newsize = (writepos - readpos) + 10;
 108                     newsize = Math.max(buffers.length * 2, newsize);
 109                     buffers = new byte[newsize][buffers[0].length];
 110                 }
 111             }
 112         }
 113 
 114         JitterStream(AudioInputStream s, int buffersize,
 115                 int smallbuffersize) {
 116             this.w_count = 10 * (buffersize / smallbuffersize);
 117             if (w_count < 100)
 118                 w_count = 100;
 119             this.buffers
 120                     = new byte[(buffersize/smallbuffersize)+10][smallbuffersize];
 121             this.bbuffer_max = MAX_BUFFER_SIZE / smallbuffersize;
 122             this.stream = s;
 123 
 124 
 125             Runnable runnable = new Runnable() {
 126 

 127                 public void run() {
 128                     AudioFormat format = stream.getFormat();
 129                     int bufflen = buffers[0].length;
 130                     int frames = bufflen / format.getFrameSize();
 131                     long nanos = (long) (frames * 1000000000.0
 132                                             / format.getSampleRate());
 133                     long now = System.nanoTime();
 134                     long next = now + nanos;
 135                     int correction = 0;
 136                     while (true) {
 137                         synchronized (JitterStream.this) {
 138                             if (!active)
 139                                 break;
 140                         }
 141                         int curbuffsize;
 142                         synchronized (buffers) {
 143                             curbuffsize = writepos - readpos;
 144                             if (correction == 0) {
 145                                 w++;
 146                                 if (w_min != Integer.MAX_VALUE) {


 203                         }
 204                         long wait = next - System.nanoTime();
 205                         if (wait > 0) {
 206                             try {
 207                                 Thread.sleep(wait / 1000000L);
 208                             } catch (InterruptedException e) {
 209                                 //e.printStackTrace();
 210                             }
 211                         }
 212                         next += nanos;
 213                     }
 214                 }
 215             };
 216 
 217             thread = new Thread(null, runnable, "JitterCorrector", 0, false);
 218             thread.setDaemon(true);
 219             thread.setPriority(Thread.MAX_PRIORITY);
 220             thread.start();
 221         }
 222 

 223         public void close() throws IOException {
 224             synchronized (this) {
 225                 active = false;
 226             }
 227             try {
 228                 thread.join();
 229             } catch (InterruptedException e) {
 230                 //e.printStackTrace();
 231             }
 232             stream.close();
 233         }
 234 

 235         public int read() throws IOException {
 236             byte[] b = new byte[1];
 237             if (read(b) == -1)
 238                 return -1;
 239             return b[0] & 0xFF;
 240         }
 241 
 242         public void fillBuffer() {
 243             bbuffer = nextReadBuffer();
 244             bbuffer_pos = 0;
 245         }
 246 

 247         public int read(byte[] b, int off, int len) {
 248             if (bbuffer == null)
 249                 fillBuffer();
 250             int bbuffer_len = bbuffer.length;
 251             int offlen = off + len;
 252             while (off < offlen) {
 253                 if (available() == 0)
 254                     fillBuffer();
 255                 else {
 256                     byte[] bbuffer = this.bbuffer;
 257                     int bbuffer_pos = this.bbuffer_pos;
 258                     while (off < offlen && bbuffer_pos < bbuffer_len)
 259                         b[off++] = bbuffer[bbuffer_pos++];
 260                     this.bbuffer_pos = bbuffer_pos;
 261                 }
 262             }
 263             return len;
 264         }
 265 

 266         public int available() {
 267             return bbuffer.length - bbuffer_pos;
 268         }
 269     }
 270 
 271     public SoftJitterCorrector(AudioInputStream stream, int buffersize,
 272             int smallbuffersize) {
 273         super(new JitterStream(stream, buffersize, smallbuffersize),
 274                 stream.getFormat(), stream.getFrameLength());
 275     }
 276 }


   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.media.sound;
  27 


  28 import java.io.EOFException;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 
  32 import javax.sound.sampled.AudioFormat;
  33 import javax.sound.sampled.AudioInputStream;
  34 
  35 /**
  36  * A jitter corrector to be used with SoftAudioPusher.
  37  *
  38  * @author Karl Helgason
  39  */
  40 public final class SoftJitterCorrector extends AudioInputStream {
  41 
  42     private static class JitterStream extends InputStream {
  43 
  44         static int MAX_BUFFER_SIZE = 1048576;
  45         boolean active = true;
  46         Thread thread;
  47         AudioInputStream stream;
  48         // Cyclic buffer
  49         int writepos = 0;
  50         int readpos = 0;
  51         byte[][] buffers;
  52         private final Object buffers_mutex = new Object();
  53 
  54         // Adapative Drift Statistics


 109                     int newsize = (writepos - readpos) + 10;
 110                     newsize = Math.max(buffers.length * 2, newsize);
 111                     buffers = new byte[newsize][buffers[0].length];
 112                 }
 113             }
 114         }
 115 
 116         JitterStream(AudioInputStream s, int buffersize,
 117                 int smallbuffersize) {
 118             this.w_count = 10 * (buffersize / smallbuffersize);
 119             if (w_count < 100)
 120                 w_count = 100;
 121             this.buffers
 122                     = new byte[(buffersize/smallbuffersize)+10][smallbuffersize];
 123             this.bbuffer_max = MAX_BUFFER_SIZE / smallbuffersize;
 124             this.stream = s;
 125 
 126 
 127             Runnable runnable = new Runnable() {
 128 
 129                 @Override
 130                 public void run() {
 131                     AudioFormat format = stream.getFormat();
 132                     int bufflen = buffers[0].length;
 133                     int frames = bufflen / format.getFrameSize();
 134                     long nanos = (long) (frames * 1000000000.0
 135                                             / format.getSampleRate());
 136                     long now = System.nanoTime();
 137                     long next = now + nanos;
 138                     int correction = 0;
 139                     while (true) {
 140                         synchronized (JitterStream.this) {
 141                             if (!active)
 142                                 break;
 143                         }
 144                         int curbuffsize;
 145                         synchronized (buffers) {
 146                             curbuffsize = writepos - readpos;
 147                             if (correction == 0) {
 148                                 w++;
 149                                 if (w_min != Integer.MAX_VALUE) {


 206                         }
 207                         long wait = next - System.nanoTime();
 208                         if (wait > 0) {
 209                             try {
 210                                 Thread.sleep(wait / 1000000L);
 211                             } catch (InterruptedException e) {
 212                                 //e.printStackTrace();
 213                             }
 214                         }
 215                         next += nanos;
 216                     }
 217                 }
 218             };
 219 
 220             thread = new Thread(null, runnable, "JitterCorrector", 0, false);
 221             thread.setDaemon(true);
 222             thread.setPriority(Thread.MAX_PRIORITY);
 223             thread.start();
 224         }
 225 
 226         @Override
 227         public void close() throws IOException {
 228             synchronized (this) {
 229                 active = false;
 230             }
 231             try {
 232                 thread.join();
 233             } catch (InterruptedException e) {
 234                 //e.printStackTrace();
 235             }
 236             stream.close();
 237         }
 238 
 239         @Override
 240         public int read() throws IOException {
 241             byte[] b = new byte[1];
 242             if (read(b) == -1)
 243                 return -1;
 244             return b[0] & 0xFF;
 245         }
 246 
 247         public void fillBuffer() {
 248             bbuffer = nextReadBuffer();
 249             bbuffer_pos = 0;
 250         }
 251 
 252         @Override
 253         public int read(byte[] b, int off, int len) {
 254             if (bbuffer == null)
 255                 fillBuffer();
 256             int bbuffer_len = bbuffer.length;
 257             int offlen = off + len;
 258             while (off < offlen) {
 259                 if (available() == 0)
 260                     fillBuffer();
 261                 else {
 262                     byte[] bbuffer = this.bbuffer;
 263                     int bbuffer_pos = this.bbuffer_pos;
 264                     while (off < offlen && bbuffer_pos < bbuffer_len)
 265                         b[off++] = bbuffer[bbuffer_pos++];
 266                     this.bbuffer_pos = bbuffer_pos;
 267                 }
 268             }
 269             return len;
 270         }
 271 
 272         @Override
 273         public int available() {
 274             return bbuffer.length - bbuffer_pos;
 275         }
 276     }
 277 
 278     public SoftJitterCorrector(AudioInputStream stream, int buffersize,
 279             int smallbuffersize) {
 280         super(new JitterStream(stream, buffersize, smallbuffersize),
 281                 stream.getFormat(), stream.getFrameLength());
 282     }
 283 }
< prev index next >