Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Mondain

By: a guest on Sep 11th, 2010  |  syntax: Java  |  size: 3.46 KB  |  views: 643  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. public class Track {
  2.  
  3.         private static Logger log = LoggerFactory.getLogger(Track.class);
  4.  
  5.         private final long id = System.nanoTime();
  6.  
  7.         // number of channels
  8.         private int channelCount;
  9.  
  10.         // maximum seconds to buffer
  11.         private int bufferedSeconds = 5;
  12.  
  13.         private AtomicInteger count = new AtomicInteger(0);
  14.  
  15.         private ReentrantLock lock;
  16.  
  17.         private volatile short[] buffer;
  18.  
  19.         private int capacity = 0;
  20.  
  21.         private int head = 0;
  22.  
  23.         private int tail = 0;
  24.  
  25.         public Track(int samplingRate, int channelCount) {
  26.                 // set the number of channels
  27.                 this.channelCount = channelCount;
  28.                 // size the buffer
  29.                 capacity = (samplingRate * channelCount) * bufferedSeconds;
  30.                 buffer = new short[capacity];
  31.                 // use a "fair" lock
  32.                 lock = new ReentrantLock(true);
  33.         }
  34.  
  35.         /**
  36.          * Returns the number of samples currently in the buffer.
  37.          *
  38.          * @return
  39.          */
  40.         public int getSamplesCount() {
  41.                 int i = count.get();
  42.                 return i > 0 ? i / channelCount : 0;
  43.         }
  44.  
  45.         /**
  46.          * Removes and returns the next sample in the buffer.
  47.          *
  48.          * @return single sample or null if a buffer underflow occurs
  49.          */
  50.         public Short remove() {
  51.                 Short sample = null;
  52.                 if (count.get() > 0) {
  53.                         // decrement sample counter
  54.                         count.addAndGet(-1);
  55.                         // reposition the head
  56.                         head = (head + 1) % capacity;
  57.                         // get the sample at the head
  58.                         sample = buffer[head];
  59.                 } else {
  60.                         log.debug("Buffer underflow");
  61.                 }
  62.                 return sample;
  63.         }
  64.  
  65.         /**
  66.          * Adds a sample to the buffer.
  67.          *
  68.          * @param sample
  69.          * @return true if added successfully and false otherwise
  70.          */
  71.         public boolean add(short sample) {
  72.                 boolean result = false;
  73.                 if ((count.get() + 1) < capacity) {
  74.                         // increment sample counter
  75.                         count.addAndGet(1);
  76.                         // reposition the tail
  77.                         tail = (tail + 1) % capacity;
  78.                         // add the sample to the tail
  79.                         buffer[tail] = sample;
  80.                         // added!
  81.                         result = true;
  82.                 } else {
  83.                         log.debug("Buffer overflow");
  84.                 }
  85.                 return result;
  86.         }
  87.  
  88.         /**
  89.          * Offers the samples for addition to the buffer, if there is enough capacity to
  90.          * contain them they will be added.
  91.          *
  92.          * @param samples
  93.          * @return true if the samples can be added and false otherwise
  94.          */
  95.         public boolean offer(short[] samples) {
  96.                 boolean result = false;
  97.                 if ((count.get() + samples.length) <= capacity) {
  98.                         pushSamples(samples);
  99.                         result = true;
  100.                 }
  101.                 return result;
  102.         }
  103.  
  104.         /**
  105.          * Adds an array of samples to the buffer.
  106.          *
  107.          * @param samples
  108.          */
  109.         public void pushSamples(short[] samples) {
  110.                 log.trace("[{}] pushSamples - count: {}", id, samples.length);
  111.                 try {
  112.                         lock.tryLock(10, TimeUnit.MILLISECONDS);
  113.                         for (short sample : samples) {
  114.                                 log.trace("Position at write: {}", tail);
  115.                                 if (!add(sample)) {
  116.                                         log.warn("Sample could not be added");
  117.                                         break;
  118.                                 }
  119.                         }
  120.                 } catch (InterruptedException e) {
  121.                         log.warn("Exception getting samples", e);
  122.                 } finally {
  123.                         if (lock.isHeldByCurrentThread()) {
  124.                                 lock.unlock();
  125.                         }
  126.                 }
  127.         }
  128.  
  129.         /**
  130.          * Returns a single from the buffer.
  131.          *
  132.          * @return
  133.          */
  134.         public Short popSample(int channel) {
  135.                 log.trace("[{}] popSample - channel: {}", id, channel);
  136.                 Short sample = null;
  137.                 if (channel < channelCount) {
  138.                         log.trace("Position at read: {}", head);
  139.                         try {
  140.                                 lock.tryLock(10, TimeUnit.MILLISECONDS);
  141.                                 sample = remove();
  142.                         } catch (InterruptedException e) {
  143.                                 log.warn("Exception getting sample", e);
  144.                         } finally {
  145.                                 if (lock.isHeldByCurrentThread()) {
  146.                                         lock.unlock();
  147.                                 }
  148.                         }
  149.                 }
  150.                 return sample;
  151.         }
  152. }