001/*
002 *  -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*-
003 */
004/*
005 *  TOM Gutwin's fork of...
006 *  JOrbisPlayer -- pure Java Ogg Vorbis player
007 *
008 *  Copyright (C) 2000 ymnk, JCraft,Inc.
009 *
010 *  Written by: 2000 ymnk<ymnk@jcraft.com>
011 *
012 *  Many thanks to
013 *  Monty <monty@xiph.org> and
014 *  The XIPHOPHORUS Company http://www.xiph.org/ .
015 *  JOrbis has been based on their awesome works, Vorbis codec and
016 *  JOrbisPlayer depends on JOrbis.
017 *
018 *  This program is free software; you can redistribute it and/or modify
019 *  it under the terms of the GNU General Public License as published by
020 *  the Free Software Foundation; either version 2 of the License, or
021 *  (at your option) any later version.
022 *
023 *  This program is distributed in the hope that it will be useful,
024 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
025 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
026 *  GNU General Public License for more details.
027 *
028 *  You should have received a copy of the GNU General Public License
029 *  along with this program; if not, write to the Free Software
030 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
031 */
032
033package ca.bc.webarts;
034
035import com.jcraft.jogg.*;
036
037import com.jcraft.jorbis.*;
038import java.applet.*;
039import java.awt.*;
040import java.awt.event.*;
041import java.io.*;
042import java.net.*;
043
044import java.util.*;
045
046import javax.sound.midi.*;
047import javax.sound.sampled.*;
048import javax.swing.*;
049
050
051/**
052 *  Description of the Class
053 *
054 * @author    tgutwin
055 */
056public class JOrbisPlayer extends JApplet implements ActionListener, Runnable
057{
058
059  /**  Description of the Field */
060  final static int BUFSIZE = 4096 * 3;
061  /**  Description of the Field */
062  private int RETRY = 3;
063
064
065  /**  Description of the Field */
066  static AppletContext acontext = null;
067  /**  Description of the Field */
068  static int convsize = BUFSIZE * 2;
069  /**  Description of the Field */
070  static byte[] convbuffer = new byte[convsize];
071
072  /**  Description of the Field */
073  public boolean running_as_applet = true;
074
075  /**  Description of the Field */
076  Thread player = null;
077  /**  Description of the Field */
078  InputStream bitStream = null;
079
080  /**  Description of the Field */
081  int udp_port = -1;
082  /**  Description of the Field */
083  String udp_baddress = null;
084  /**  Description of the Field */
085  int retry = RETRY;
086
087  /**  Description of the Field */
088  String playlistfile = "playlist";
089
090  /**  Description of the Field */
091  boolean icestats = false;
092
093  /**  Description of the Field */
094  SyncState oy;
095  /**  Description of the Field */
096  StreamState os;
097  /**  Description of the Field */
098  Page og;
099  /**  Description of the Field */
100  Packet op;
101  /**  Description of the Field */
102  Info vi;
103  /**  Description of the Field */
104  Comment vc;
105  /**  Description of the Field */
106  DspState vd;
107  /**  Description of the Field */
108  Block vb;
109
110  /**  Description of the Field */
111  byte[] buffer = null;
112  /**  Description of the Field */
113  int bytes = 0;
114
115  /**  Description of the Field */
116  int format;
117  /**  Description of the Field */
118  int rate = 0;
119  /**  Description of the Field */
120  int channels = 0;
121  /**  Description of the Field */
122  int left_vol_scale = 100;
123  /**  Description of the Field */
124  int right_vol_scale = 100;
125  /**  Description of the Field */
126  SourceDataLine outputLine = null;
127  /**  Description of the Field */
128  String current_source = null;
129
130  /**  Description of the Field */
131  int frameSizeInBytes;
132  /**  Description of the Field */
133  int bufferLengthInBytes;
134
135  /**  Description of the Field */
136  boolean playonstartup = true;
137
138  boolean playing_ = false;
139
140  public boolean noGui = true;
141
142  /**
143     * These variables are used to distinguish stopped, paused, playing states.
144     * We need them to control Thread.
145     */
146    public static final int UNKNOWN = -1;
147    public static final int PLAYING = 0;
148    public static final int PAUSED = 1;
149    public static final int STOPPED = 2;
150    public static final int OPENED = 3;
151    public static final int SEEKING = 4;
152    private int m_status = UNKNOWN;
153
154  /**
155   * Description of the Field
156   */
157  private boolean loopPaused_ = false;
158  /**
159   * Description of the Field
160   */
161  boolean timerRunning_ = false;
162
163
164  /**  Description of the Field */
165  public Vector playlist = new Vector();
166
167  /**  Description of the Field */
168  JPanel panel;
169  /**  Description of the Field */
170  JComboBox cb;
171  /**  Description of the Field */
172  JButton start_button;
173  /**  Description of the Field */
174  JButton stats_button;
175
176
177  /**  Constructor for the JOrbisPlayer object */
178  public JOrbisPlayer() { }
179
180
181  /**
182   *  The main program for the JOrbisPlayer class
183   *
184   * @param  arg  The command line arguments
185   */
186  public static void main(String[] arg)
187  {
188
189    JFrame frame = new JFrame("JOrbisPlayer");
190    frame.setBackground(Color.lightGray);
191    frame.setBackground(Color.white);
192    frame.getContentPane().setLayout(new BorderLayout());
193
194    frame.addWindowListener(
195      new WindowAdapter()
196      {
197        public void windowClosing(WindowEvent e)
198        {
199          System.exit(0);
200        }
201      });//ende WindowListener
202
203    JOrbisPlayer player = new JOrbisPlayer();
204    player.noGui = false;
205    player.running_as_applet = false;
206
207    if (arg.length > 0)
208    {
209      for (int i = 0; i < arg.length; i++)
210      {
211        player.playlist.addElement(arg[i]);
212      }
213    }
214
215    player.loadPlaylist();
216    player.initUI();
217
218    frame.getContentPane().add(player.panel);
219    frame.pack();
220    frame.setVisible(true);
221    player.start();
222  }
223
224
225  /**
226   *  Handles the gui action events
227   *
228   * @param  e  Description of the Parameter
229   */
230  public void actionPerformed(ActionEvent e)
231  {
232
233    if (e.getSource() == stats_button)
234    {
235      String item = (String) (cb.getSelectedItem());
236      if (!item.startsWith("http://"))
237      {
238        return;
239      }
240      if (item.endsWith(".pls"))
241      {
242        item = fetch_pls(item);
243        if (item == null)
244        {
245          return;
246        }
247      }
248      else if (item.endsWith(".m3u"))
249      {
250        item = fetch_m3u(item);
251        if (item == null)
252        {
253          return;
254        }
255      }
256      byte[] foo = item.getBytes();
257      for (int i = foo.length - 1; i >= 0; i--)
258      {
259        if (foo[i] == '/')
260        {
261          item = item.substring(0, i + 1) + "stats.xml";
262          break;
263        }
264      }
265      System.out.println(item);
266      try
267      {
268        URL url = null;
269        if (running_as_applet)
270        {
271          url = new URL(getCodeBase(), item);
272        }
273        else
274        {
275          url = new URL(item);
276        }
277        BufferedReader stats = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream()));
278        while (true)
279        {
280          String bar = stats.readLine();
281          if (bar == null)
282          {
283            break;
284          }
285          System.out.println(bar);
286        }
287      }
288      catch (Exception ee)
289      {
290        //System.err.println(ee);
291      }
292      return;
293    }
294
295    String command = ((JButton) (e.getSource())).getText();
296    if (command.equals("start") && player == null)
297    {
298      play_sound();
299    }
300    else if (player != null)
301    {
302      stop_sound();
303    }
304  }
305
306
307  /**
308   *  Looks up the JComboBox item and returns the index of the item.
309   *
310   * @param  item  the combo box item string
311   * @return       the index of the item.
312   */
313  private int item2index(String item)
314  {
315    for (int i = 0; i < cb.getItemCount(); i++)
316    {
317      String foo = (String) (cb.getItemAt(i));
318      if (item.equals(foo))
319      {
320        return i;
321      }
322    }
323    cb.addItem(item);
324    return cb.getItemCount() - 1;
325  }
326
327
328
329  /**  Initializes  stuff. */
330  public void init()
331  {
332    running_as_applet = !noGui ;
333
334    if(!noGui) acontext = getAppletContext();
335
336    String s = getParameter("jorbis.player.playlist");
337    playlistfile = s;
338
339    s = getParameter("jorbis.player.icestats");
340    if (s != null && s.equals("yes"))
341    {
342      icestats = true;
343    }
344
345    loadPlaylist();
346    if(!noGui) initUI();
347
348    if (playlist.size() > 0)
349    {
350      s = getParameter("jorbis.player.playonstartup");
351      if (s != null && s.equals("yes"))
352      {
353        playonstartup = true;
354      }
355    }
356
357    if(!noGui) setBackground(Color.lightGray);
358    //  setBackground(Color.white);
359    if(!noGui) getContentPane().setLayout(new BorderLayout());
360    if(!noGui) getContentPane().add(panel);
361  }
362
363
364  /**  Description of the Method */
365  public void start()
366  {
367    if(!noGui) super.start();
368    //if (playonstartup)
369    {
370      play_sound();
371    }
372  }
373
374
375  /**  Main processing thread method for the JOrbisPlayer object */
376  public void run()
377  {
378    Thread me = Thread.currentThread();
379    System.out.println("   >Starting JOrbisPlayer Thread: "+ me.getId());
380    int current_index = 0;
381    String item = (String) playlist.get(current_index);
382    if(cb!=null) item =  (String) (cb.getSelectedItem());
383    if(start_button!=null) current_index = item2index(item);
384    System.out.println("\n JOrbisPlayer Thread starting to play item: "+item);
385    while (true)
386    {
387      if(cb!=null) item = (String) (cb.getItemAt(current_index));
388      if(cb!=null) cb.setSelectedIndex(current_index);
389      bitStream = selectSource(item);
390      if (bitStream != null)
391      {
392        if (udp_port != -1)
393        {
394          play_udp_stream(me);
395        }
396        else
397        {
398          play_stream(me);
399        }
400      }
401      if (player != me)
402      {
403        break;
404      }
405      bitStream = null;
406      current_index++;
407      if (current_index >= playlist.size())// cb.getItemCount())
408      {
409        current_index = 0;
410      }
411      if (playlist.size() <=0) //  cb.getItemCount() <= 0)
412      {
413        break;
414      }
415    }
416    player = null;
417    if(start_button!=null) start_button.setText("start");
418    System.out.println("   <Exitingting JOrbisPlayer Thread: "+ me.getId());
419  }
420
421
422  protected void togglePause()
423  {
424    if (m_status == PLAYING)      pausePlayback();
425    else if (m_status == PAUSED) resumePlayback();
426  }
427
428
429  /**
430   * Pauses the playback.<br>
431   *
432   * Player Status = PAUSED.
433   */
434  protected void pausePlayback()
435  {
436      if (outputLine != null)
437      {
438          if (m_status == PLAYING)
439          {
440              outputLine.drain();    //flush();
441              outputLine.stop();
442              m_status = PAUSED;
443              //log.info("pausePlayback() completed");
444              //notifyEvent(BasicPlayerEvent.PAUSED, getEncodedStreamPosition(), -1, null);
445          }
446      }
447  }
448
449  /**
450   * Resumes the playback.<br>
451   *
452   * Player Status = PLAYING.
453   */
454  protected void resumePlayback()
455  {
456      if (outputLine != null)
457      {
458          if (m_status == PAUSED)
459          {
460              outputLine.start();
461              m_status = PLAYING;
462              //log.info("resumePlayback() completed");
463              //notifyEvent(BasicPlayerEvent.RESUMED, getEncodedStreamPosition(), -1, null);
464          }
465      }
466  }
467
468
469  /**
470    * Set Method for class field 'loopPaused_'.
471    *
472    * @param loopPaused is the value to set this class field to.
473    *
474    **/
475  public synchronized void setLoopPaused(boolean loopPaused)
476  {
477    this.loopPaused_ = loopPaused;
478  }  // setLoopPaused Method
479
480
481  /**
482    * Get Method for class field 'loopPaused_'.
483    *
484    * @return boolean - The value the class field 'loopPaused_'.
485    *
486    **/
487  public synchronized boolean getLoopPaused()
488  {
489    return loopPaused_;
490  }  // getLoopPaused Method
491
492
493  /**
494   *  Gets the title attribute of the JOrbisPlayer object
495   *
496   * @return    The title value
497   */
498  public String getTitle()
499  {
500    return (String) (cb.getSelectedItem());
501  }
502
503
504  /**  Description of the Method */
505  public void play_sound()
506  {
507    if (!noGui && player != null)
508    {
509      return;
510    }
511    player = new Thread(this);
512    if(start_button!=null) start_button.setText("stop");
513    player.start();
514    m_status = PLAYING;
515  }
516
517
518  /**
519    *  Stop the playback
520    *  Player Status = STOPPED.
521    **/
522  public void stop()
523  {
524    if (player != null)
525    {
526      try
527      {
528        System.out.println(" Closing JOrbisPlayer.outputLines"+ Thread.currentThread().getId());
529        outputLine.drain();
530        outputLine.stop();
531        outputLine.close();
532        if (bitStream != null)
533        {
534          bitStream.close();
535        }
536      }
537      catch (Exception e)
538      {
539        System.out.println(" error closing JOrbisPlayer output streams: "+e.getMessage());
540      }
541    }
542    player = null;
543    m_status = STOPPED;
544  }
545
546
547  /**  Description of the Method */
548  public void stop_sound()
549  {
550    if (!noGui && player == null)
551    {
552      return;
553    }
554    player = null;
555    m_status = STOPPED;
556    if(start_button!=null) start_button.setText("start");
557  }
558
559
560  /**  instantaites all the JOgg streams and states. */
561  void init_jorbis()
562  {
563    oy = new SyncState();
564    os = new StreamState();
565    og = new Page();
566    op = new Packet();
567
568    vi = new Info();
569    vc = new Comment();
570    vd = new DspState();
571    vb = new Block(vd);
572
573    buffer = null;
574    bytes = 0;
575
576    oy.init();
577  }
578
579
580  /**
581   *  Gets the outputLine attribute of the JOrbisPlayer object
582   *
583   * @param  channels  Description of the Parameter
584   * @param  rate      Description of the Parameter
585   * @return           The outputLine value
586   */
587  SourceDataLine getOutputLine(int channels, int rate)
588  {
589    if (outputLine == null || this.rate != rate || this.channels != channels)
590    {
591      if (outputLine != null)
592      {
593        outputLine.drain();
594        outputLine.stop();
595        outputLine.close();
596      }
597      init_audio(channels, rate);
598      outputLine.start();
599    }
600    return outputLine;
601  }
602
603
604  /**
605   *  Description of the Method
606   *
607   * @param  channels  Description of the Parameter
608   * @param  rate      Description of the Parameter
609   */
610  void init_audio(int channels, int rate)
611  {
612    try
613    {
614      //ClassLoader originalClassLoader=null;
615      //try{
616      //  originalClassLoader=Thread.currentThread().getContextClassLoader();
617      //  Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
618      //}
619      //catch(Exception ee){
620      //  System.out.println(ee);
621      //}
622      AudioFormat audioFormat =
623          new AudioFormat((float) rate,
624          16,
625          channels,
626          true, // PCM_Signed
627      false// littleEndian
628      );
629      DataLine.Info info =
630          new DataLine.Info(SourceDataLine.class,
631          audioFormat,
632          AudioSystem.NOT_SPECIFIED);
633      if (!AudioSystem.isLineSupported(info))
634      {
635        //System.out.println("Line " + info + " not supported.");
636        return;
637      }
638
639      try
640      {
641        outputLine = (SourceDataLine) AudioSystem.getLine(info);
642        //outputLine.addLineListener(this);
643        outputLine.open(audioFormat);
644      }
645      catch (LineUnavailableException ex)
646      {
647        System.out.println("Unable to open the sourceDataLine: " + ex);
648        return;
649      }
650      catch (IllegalArgumentException ex)
651      {
652        System.out.println("Illegal Argument: " + ex);
653        return;
654      }
655
656      frameSizeInBytes = audioFormat.getFrameSize();
657      int bufferLengthInFrames = outputLine.getBufferSize() / frameSizeInBytes / 2;
658      bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
659
660      //buffer = new byte[bufferLengthInBytes];
661      //if(originalClassLoader!=null)
662      //  Thread.currentThread().setContextClassLoader(originalClassLoader);
663
664      this.rate = rate;
665      this.channels = channels;
666    }
667    catch (Exception ee)
668    {
669      System.out.println(ee);
670    }
671  }
672
673
674  /**
675   *  Description of the Method
676   *
677   * @param  item  Description of the Parameter
678   * @return       Description of the Return Value
679   */
680  InputStream selectSource(String item)
681  {
682    if (item.endsWith(".pls"))
683    {
684      item = fetch_pls(item);
685      if (item == null)
686      {
687        return null;
688      }
689      //System.out.println("fetch: "+item);
690    }
691    else if (item.endsWith(".m3u"))
692    {
693      item = fetch_m3u(item);
694      if (item == null)
695      {
696        return null;
697      }
698      //System.out.println("fetch: "+item);
699    }
700
701    if (!item.endsWith(".ogg"))
702    {
703      return null;
704    }
705
706    InputStream is = null;
707    URLConnection urlc = null;
708    try
709    {
710      URL url = null;
711      if (running_as_applet)
712      {
713        url = new URL(getCodeBase(), item);
714      }
715      else
716      {
717        url = new URL(item);
718      }
719      urlc = url.openConnection();
720      is = urlc.getInputStream();
721      current_source = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + url.getFile();
722    }
723    catch (Exception ee)
724    {
725      System.err.println(ee);
726    }
727
728    if (is == null && !running_as_applet)
729    {
730      try
731      {
732        is = new FileInputStream( //System.getProperty("user.dir") +
733                                  //System.getProperty("file.separator") +
734                                  item);
735        current_source = null;
736      }
737      catch (Exception ee)
738      {
739        System.err.println(ee);
740      }
741    }
742
743    if (is == null)
744    {
745      return null;
746    }
747
748    System.out.println("Select: " + item);
749    {
750      boolean find = false;
751      for (int i = 0; i < playlist.size(); i++)
752      {
753        String foo = (String) (playlist.get(i));
754        if (item.equals(foo))
755        {
756          find = true;
757          break;
758        }
759      }
760      //if (!find)
761      // {
762      //  cb.addItem(item);
763      //}
764    }
765
766    int i = 0;
767    String s = null;
768    String t = null;
769    udp_port = -1;
770    udp_baddress = null;
771    while (urlc != null && true)
772    {
773      s = urlc.getHeaderField(i);
774      t = urlc.getHeaderFieldKey(i);
775      if (s == null)
776      {
777        break;
778      }
779      i++;
780      if (t != null && t.equals("udp-port"))
781      {
782        try
783        {
784          udp_port = Integer.parseInt(s);
785        }
786        catch (Exception ee)
787        {
788          System.err.println(ee);
789        }
790      }
791      else if (t != null && t.equals("udp-broadcast-address"))
792      {
793        udp_baddress = s;
794      }
795    }
796    return is;
797  }
798
799
800  /**
801   *  Description of the Method
802   *
803   * @param  pls  Description of the Parameter
804   * @return      Description of the Return Value
805   */
806  String fetch_pls(String pls)
807  {
808    InputStream pstream = null;
809    if (pls.startsWith("http://"))
810    {
811      try
812      {
813        URL url = null;
814        if (running_as_applet)
815        {
816          url = new URL(getCodeBase(), pls);
817        }
818        else
819        {
820          url = new URL(pls);
821        }
822        URLConnection urlc = url.openConnection();
823        pstream = urlc.getInputStream();
824      }
825      catch (Exception ee)
826      {
827        System.err.println(ee);
828        return null;
829      }
830    }
831    if (pstream == null && !running_as_applet)
832    {
833      try
834      {
835        pstream = new FileInputStream( //System.getProperty("user.dir") +
836                                       //System.getProperty("file.separator") +
837                                       pls);
838      }
839      catch (Exception ee)
840      {
841        System.err.println(ee);
842        return null;
843      }
844    }
845
846    String line = null;
847    while (true)
848    {
849      try
850      {
851        line = readline(pstream);
852      }
853      catch (Exception e)
854      {}
855      if (line == null)
856      {
857        break;
858      }
859      if (line.startsWith("File1="))
860      {
861        byte[] foo = line.getBytes();
862        int i = 6;
863        for (; i < foo.length; i++)
864        {
865          if (foo[i] == 0x0d)
866          {
867            break;
868          }
869        }
870        return line.substring(6, i);
871      }
872    }
873    return null;
874  }
875
876
877  /**
878   *  Description of the Method
879   *
880   * @param  m3u  Description of the Parameter
881   * @return      Description of the Return Value
882   */
883  String fetch_m3u(String m3u)
884  {
885    InputStream pstream = null;
886    if (m3u.startsWith("http://"))
887    {
888      try
889      {
890        URL url = null;
891        if (running_as_applet)
892        {
893          url = new URL(getCodeBase(), m3u);
894        }
895        else
896        {
897          url = new URL(m3u);
898        }
899        URLConnection urlc = url.openConnection();
900        pstream = urlc.getInputStream();
901      }
902      catch (Exception ee)
903      {
904        System.err.println(ee);
905        return null;
906      }
907    }
908    if (pstream == null && !running_as_applet)
909    {
910      try
911      {
912        pstream = new FileInputStream( //System.getProperty("user.dir") +
913                                       //System.getProperty("file.separator") +
914                                       m3u);
915      }
916      catch (Exception ee)
917      {
918        System.err.println(ee);
919        return null;
920      }
921    }
922
923    String line = null;
924    while (true)
925    {
926      try
927      {
928        line = readline(pstream);
929      }
930      catch (Exception e)
931      {}
932      if (line == null)
933      {
934        break;
935      }
936      return line;
937    }
938    return null;
939  }
940
941
942  /**  Description of the Method */
943  public void loadPlaylist()
944  {
945    if (running_as_applet)
946    {
947      String s = null;
948      for (int i = 0; i < 10; i++)
949      {
950        s = getParameter("jorbis.player.play." + i);
951        if (s == null)
952        {
953          break;
954        }
955        playlist.addElement(s);
956      }
957    }
958
959    if (playlistfile == null)
960    {
961      return;
962    }
963
964    try
965    {
966      InputStream is = null;
967      try
968      {
969        URL url = null;
970        if (running_as_applet)
971        {
972          url = new URL(getCodeBase(), playlistfile);
973        }
974        else
975        {
976          url = new URL(playlistfile);
977        }
978        URLConnection urlc = url.openConnection();
979        is = urlc.getInputStream();
980      }
981      catch (Exception ee)
982      {}
983      if (is == null && !running_as_applet)
984      {
985        try
986        {
987          is = new FileInputStream(  //System.getProperty("user.dir") +
988                                     //System.getProperty("file.separator") +
989                                     playlistfile);
990        }
991        catch (Exception ee)
992        {}
993      }
994
995      if (is == null)
996      {
997        return;
998      }
999
1000      while (true)
1001      {
1002        String line = readline(is);
1003        if (line == null)
1004        {
1005          break;
1006        }
1007        byte[] foo = line.getBytes();
1008        for (int i = 0; i < foo.length; i++)
1009        {
1010          if (foo[i] == 0x0d)
1011          {
1012            line = new String(foo, 0, i);
1013            break;
1014          }
1015        }
1016        playlist.addElement(line);
1017      }
1018    }
1019    catch (Exception e)
1020    {
1021      System.out.println(e);
1022    }
1023  }
1024
1025
1026  /**  Gets all the GUI panel and buttons init. */
1027  void initUI()
1028  {
1029    panel = new JPanel();
1030
1031    cb = new JComboBox(playlist);
1032    cb.setEditable(true);
1033    panel.add(cb);
1034
1035    start_button = new JButton("start");
1036    start_button.addActionListener(this);
1037    panel.add(start_button);
1038
1039    if (icestats)
1040    {
1041      stats_button = new JButton("IceStats");
1042      stats_button.addActionListener(this);
1043      panel.add(stats_button);
1044    }
1045  }
1046
1047
1048  /**
1049   *  Description of the Method
1050   *
1051   * @param  me  Description of the Parameter
1052   */
1053  private void play_stream(Thread me)
1054  {
1055    int last_channels = -1;
1056    int last_rate = -1;
1057
1058    boolean chained = false;
1059
1060    init_jorbis();
1061
1062    retry = RETRY;
1063
1064    System.out.println("play_stream>");
1065
1066    loop :
1067    while (true)
1068    {
1069      int eos = 0;
1070
1071      int index = oy.buffer(BUFSIZE);
1072      buffer = oy.data;
1073      try
1074      {
1075        bytes = bitStream.read(buffer, index, BUFSIZE);
1076      }
1077      catch (Exception e)
1078      {
1079        System.err.println(e);
1080        return;
1081      }
1082      oy.wrote(bytes);
1083
1084      if (chained)
1085      {//
1086        chained = false;//
1087      }//
1088      else
1089      {//
1090        if (oy.pageout(og) != 1)
1091        {
1092          if (bytes < BUFSIZE)
1093          {
1094            break;
1095          }
1096          System.err.println("Input does not appear to be an Ogg bitstream.");
1097          return;
1098        }
1099      }//
1100      os.init(og.serialno());
1101      os.reset();
1102
1103      vi.init();
1104      vc.init();
1105
1106      if (os.pagein(og) < 0)
1107      {
1108        // error; stream version mismatch perhaps
1109        System.err.println("Error reading first page of Ogg bitstream data.");
1110        return;
1111      }
1112
1113      retry = RETRY;
1114
1115      if (os.packetout(op) != 1)
1116      {
1117        // no page? must not be vorbis
1118        System.err.println("Error reading initial header packet.");
1119        break;
1120        //      return;
1121      }
1122
1123      if (vi.synthesis_headerin(vc, op) < 0)
1124      {
1125        // error case; not a vorbis header
1126        System.err.println("This Ogg bitstream does not contain Vorbis audio data.");
1127        return;
1128      }
1129
1130      int i = 0;
1131
1132      while (i < 2)
1133      {
1134        while (i < 2)
1135        {
1136          int result = oy.pageout(og);
1137          if (result == 0)
1138          {
1139            break;
1140          }// Need more data
1141          if (result == 1)
1142          {
1143            os.pagein(og);
1144            while (i < 2)
1145            {
1146              result = os.packetout(op);
1147              if (result == 0)
1148              {
1149                break;
1150              }
1151              if (result == -1)
1152              {
1153                System.err.println("Corrupt secondary header.  Exiting.");
1154                //return;
1155                break loop;
1156              }
1157              vi.synthesis_headerin(vc, op);
1158              i++;
1159            }
1160          }
1161        }
1162
1163        index = oy.buffer(BUFSIZE);
1164        buffer = oy.data;
1165        try
1166        {
1167          bytes = bitStream.read(buffer, index, BUFSIZE);
1168        }
1169        catch (Exception e)
1170        {
1171          System.err.println(e);
1172          return;
1173        }
1174        if (bytes == 0 && i < 2)
1175        {
1176          System.err.println("End of file before finding all Vorbis headers!");
1177          return;
1178        }
1179        oy.wrote(bytes);
1180      }
1181      {
1182        byte[][] ptr = vc.user_comments;
1183        StringBuffer sb = null;
1184        if (acontext != null)
1185        {
1186          sb = new StringBuffer();
1187        }
1188
1189        String currComment = "";
1190        String coverImage = "";
1191        for (int j = 0; j < ptr.length; j++)
1192        {
1193          if (ptr[j] == null)
1194          {
1195            break;
1196          }
1197          currComment = new String(ptr[j], 0, ptr[j].length - 1);
1198          if(currComment.length()<"METADATA_BLOCK_PICTURE".length() ||
1199             !"METADATA_BLOCK_PICTURE".equalsIgnoreCase(currComment.substring(0,"METADATA_BLOCK_PICTURE".length()) ))
1200            System.out.println("Comment: " +currComment );
1201          else
1202          {
1203            coverImage = currComment;
1204            System.out.println("Comment: " +"METADATA_BLOCK_PICTURE="+"imageData..." );
1205          }
1206          if (sb != null)
1207          {
1208            sb.append(" " + new String(ptr[j], 0, ptr[j].length - 1));
1209          }
1210        }
1211        System.out.println("Bitstream is " + vi.channels + " channel, " + vi.rate + "Hz");
1212        if(vc!=null&& vc.vendor!=null)
1213          System.out.println("Encoded by: " + new String(vc.vendor, 0, vc.vendor.length - 1) + "\n");
1214        if (sb != null)
1215        {
1216          acontext.showStatus(sb.toString());
1217        }
1218      }
1219
1220      convsize = BUFSIZE / vi.channels;
1221
1222      vd.synthesis_init(vi);
1223      vb.init(vd);
1224
1225      double[][][] _pcm = new double[1][][];
1226      float[][][] _pcmf = new float[1][][];
1227      int[] _index = new int[vi.channels];
1228
1229      getOutputLine(vi.channels, vi.rate);
1230
1231      System.out.print("    Decoding ");
1232
1233      while (eos == 0)
1234      {
1235        while (eos == 0)
1236        {
1237
1238          if (false && player != me)
1239          {
1240            System.err.println("player!=me bye.");
1241            try
1242            {
1243              //outputLine.drain();
1244              //outputLine.stop();
1245              //outputLine.close();
1246              bitStream.close();
1247            }
1248            catch (Exception ee)
1249            {}
1250            return;
1251          }
1252
1253          int result = oy.pageout(og);
1254          if (result == 0)
1255          {
1256            break;
1257          }// need more data
1258          if (result == -1)
1259          {
1260            // missing or corrupt data at this page position
1261                  System.err.println("Corrupt or missing data in bitstream; continuing...");
1262          }
1263          else
1264          {
1265            os.pagein(og);
1266
1267            if (og.granulepos() == 0)
1268            {//
1269              chained = true;//
1270              eos = 1;//
1271              break;//
1272            }//
1273
1274            while (true)
1275            {
1276              result = os.packetout(op);
1277              if (result == 0)
1278              {
1279                break;
1280              }// need more data
1281              if (result == -1)
1282              {// missing or corrupt data at this page position
1283                // no reason to complain; already complained above
1284
1285                System.err.println("no reason to complain; already complained above");
1286              }
1287              else
1288              {
1289                // we have a packet.  Decode it
1290                int samples;
1291                if (vb.synthesis(op) == 0)
1292                {// test for success!
1293                  vd.synthesis_blockin(vb);
1294                }
1295                while ((samples = vd.synthesis_pcmout(_pcmf, _index)) > 0)
1296                {
1297                  //System.out.print(".");
1298                  double[][] pcm = _pcm[0];
1299                  float[][] pcmf = _pcmf[0];
1300                  boolean clipflag = false;
1301                  int bout = (samples < convsize ? samples : convsize);
1302
1303                  // convert doubles to 16 bit signed ints (host order) and
1304                  // interleave
1305                  for (i = 0; i < vi.channels; i++)
1306                  {
1307                    int ptr = i * 2;
1308                    //int ptr=i;
1309                    int mono = _index[i];
1310                    for (int j = 0; j < bout; j++)
1311                    {
1312                      int val = (int) (pcmf[i][mono + j] * 32767.);
1313                      if (val > 32767)
1314                      {
1315                        val = 32767;
1316                        clipflag = true;
1317                      }
1318                      if (val < -32768)
1319                      {
1320                        val = -32768;
1321                        clipflag = true;
1322                      }
1323                      if (val < 0)
1324                      {
1325                        val = val | 0x8000;
1326                      }
1327                      convbuffer[ptr] = (byte) (val);
1328                      convbuffer[ptr + 1] = (byte) (val >>> 8);
1329                      ptr += 2 * (vi.channels);
1330                    }
1331                  }
1332                  outputLine.write(convbuffer, 0, 2 * vi.channels * bout);
1333                  vd.synthesis_read(bout);
1334                }
1335                // Pause the stream
1336                while (getLoopPaused())
1337                {
1338                  ca.bc.webarts.widgets.Util.sleep(250);
1339                }
1340              }
1341            }
1342            if (og.eos() != 0)
1343            {
1344              eos = 1;
1345            }
1346          }
1347          //System.out.print(">>>");
1348        }
1349        //System.out.println("!");
1350
1351        if (eos == 0)
1352        {
1353          index = oy.buffer(BUFSIZE);
1354          buffer = oy.data;
1355          try
1356          {
1357            bytes = bitStream.read(buffer, index, BUFSIZE);
1358          }
1359          catch (Exception e)
1360          {
1361            System.err.println(e);
1362            return;
1363          }
1364          if (bytes == -1)
1365          {
1366            //System.err.println("bytes==-1");
1367            break;
1368          }
1369          oy.wrote(bytes);
1370          if (bytes == 0)
1371          {
1372            eos = 1;
1373          }
1374        }
1375      }
1376      System.out.println("DONE Decoding ");
1377
1378      //if(bytes==-1){
1379      //  retry--;
1380      //  if(retry!=0 && current_source!=null){
1381      //    System.out.println("Connection is dropped. Retry("+retry+")");
1382      //    init_jorbis();
1383      //    try { if(bitStream!=null)bitStream.close(); }
1384      //    catch(Exception e) { System.out.println(e); }
1385      //    try{Thread.sleep(1000);}
1386      //    catch(Exception e) { }
1387      //    try{
1388      //      URL url=new URL(current_source);
1389      //      URLConnection urlc=url.openConnection();
1390      //      bitStream=urlc.getInputStream();
1391      //      continue;
1392      //    }
1393      //    catch(Exception e){
1394      //      retry=0;
1395      //    }
1396      //  }
1397      //}
1398
1399      os.clear();
1400      vb.clear();
1401      vd.clear();
1402      vi.clear();
1403    }
1404
1405    oy.clear();
1406
1407    //System.out.println("play_stream<");
1408    //System.err.println("Done.");
1409
1410    try
1411    {
1412      if (bitStream != null)
1413      {
1414        bitStream.close();
1415      }
1416    }
1417    catch (Exception e)
1418    {}
1419  }
1420
1421
1422  /**
1423   *  Description of the Method
1424   *
1425   * @param  me  Description of the Parameter
1426   */
1427  private void play_udp_stream(Thread me)
1428  {
1429    init_jorbis();
1430
1431    boolean firstloop = true;
1432
1433    try
1434    {
1435      loop :
1436      while (true)
1437      {
1438        int eos = 0;
1439        int index = oy.buffer(BUFSIZE);
1440        buffer = oy.data;
1441        try
1442        {
1443          bytes = bitStream.read(buffer, index, BUFSIZE);
1444        }
1445        catch (Exception e)
1446        {
1447          System.err.println(e);
1448          return;
1449        }
1450
1451        oy.wrote(bytes);
1452        if (oy.pageout(og) != 1)
1453        {
1454//        if(bytes<BUFSIZE)break;
1455          System.err.println("Input does not appear to be an Ogg bitstream.");
1456          return;
1457        }
1458
1459        os.init(og.serialno());
1460        os.reset();
1461
1462        vi.init();
1463        vc.init();
1464        if (os.pagein(og) < 0)
1465        {
1466          // error; stream version mismatch perhaps
1467          System.err.println("Error reading first page of Ogg bitstream data.");
1468          return;
1469        }
1470
1471        if (os.packetout(op) != 1)
1472        {
1473          // no page? must not be vorbis
1474          System.err.println("Error reading initial header packet.");
1475//        break;
1476          return;
1477        }
1478
1479        if (vi.synthesis_headerin(vc, op) < 0)
1480        {
1481          // error case; not a vorbis header
1482          System.err.println("This Ogg bitstream does not contain Vorbis audio data.");
1483          return;
1484        }
1485
1486        int i = 0;
1487        while (i < 2)
1488        {
1489          while (i < 2)
1490          {
1491            int result = oy.pageout(og);
1492            if (result == 0)
1493            {
1494              break;
1495            }// Need more data
1496            if (result == 1)
1497            {
1498              os.pagein(og);
1499              while (i < 2)
1500              {
1501                result = os.packetout(op);
1502                if (result == 0)
1503                {
1504                  break;
1505                }
1506                if (result == -1)
1507                {
1508                  System.err.println("Corrupt secondary header.  Exiting.");
1509                  //return;
1510                  break loop;
1511                }
1512                vi.synthesis_headerin(vc, op);
1513                i++;
1514              }
1515            }
1516          }
1517
1518          if (i == 2)
1519          {
1520            break;
1521          }
1522
1523          index = oy.buffer(BUFSIZE);
1524          buffer = oy.data;
1525          try
1526          {
1527            bytes = bitStream.read(buffer, index, BUFSIZE);
1528          }
1529          catch (Exception e)
1530          {
1531            System.err.println(e);
1532            return;
1533          }
1534          if (bytes == 0 && i < 2)
1535          {
1536            System.err.println("End of file before finding all Vorbis headers!");
1537            return;
1538          }
1539          oy.wrote(bytes);
1540        }
1541        break;
1542      }
1543    }
1544    catch (Exception e)
1545    {
1546    }
1547
1548    try
1549    {
1550      bitStream.close();
1551    }
1552    catch (Exception e)
1553    {}
1554
1555    UDPIO io = null;
1556    try
1557    {
1558      io = new UDPIO(udp_port);
1559    }
1560    catch (Exception e)
1561    {
1562      return;
1563    }
1564
1565    bitStream = io;
1566    play_stream(me);
1567
1568    /*
1569     *  oy.init();
1570     *  loop:
1571     *  while(true){
1572     *  int eos=0;
1573     *  int index=oy.buffer(BUFSIZE);
1574     *  buffer=oy.data;
1575     *  try{ bytes=io.getByte(buffer, index, BUFSIZE); }
1576     *  catch(Exception e){
1577     *  System.err.println(e);
1578     *  return;
1579     *  }
1580     *  oy.wrote(bytes);
1581     *  if(!firstloop){
1582     *  if(oy.pageout(og)!=1){
1583     *  if(bytes<BUFSIZE)break;
1584     *  System.err.println("Input does not appear to be an Ogg bitstream.");
1585     *  return;
1586     *  }
1587     *  os.init(og.serialno());
1588     *  os.reset();
1589     *  vi.init();
1590     *  vc.init();
1591     *  if(os.pagein(og)<0){
1592     *  / error; stream version mismatch perhaps
1593     *  System.err.println("Error reading first page of Ogg bitstream data.");
1594     *  return;
1595     *  }
1596     *  if(os.packetout(op)!=1){
1597     *  / no page? must not be vorbis
1598     *  System.err.println("Error reading initial header packet.");
1599     *  break;
1600     *  /      return;
1601     *  }
1602     *  if(vi.synthesis_headerin(vc, op)<0){
1603     *  / error case; not a vorbis header
1604     *  System.err.println("This Ogg bitstream does not contain Vorbis audio data.");
1605     *  return;
1606     *  }
1607     *  int i=0;
1608     *  while(i<2){
1609     *  while(i<2){
1610     *  int result=oy.pageout(og);
1611     *  if(result==0) break; // Need more data
1612     *  if(result==1){
1613     *  os.pagein(og);
1614     *  while(i<2){
1615     *  result=os.packetout(op);
1616     *  if(result==0)break;
1617     *  if(result==-1){
1618     *  System.err.println("Corrupt secondary header.  Exiting.");
1619     *  /return;
1620     *  break loop;
1621     *  }
1622     *  vi.synthesis_headerin(vc, op);
1623     *  i++;
1624     *  }
1625     *  }
1626     *  }
1627     *  index=oy.buffer(BUFSIZE);
1628     *  buffer=oy.data;
1629     *  try{ bytes=io.getByte(buffer, index, BUFSIZE); }
1630     *  catch(Exception e){
1631     *  System.err.println(e);
1632     *  return;
1633     *  }
1634     *  if(bytes==0 && i<2){
1635     *  System.err.println("End of file before finding all Vorbis headers!");
1636     *  return;
1637     *  }
1638     *  oy.wrote(bytes);
1639     *  }
1640     *  }
1641     *  else{
1642     *  firstloop=false;
1643     *  }
1644     *  {
1645     *  byte[][] ptr=vc.user_comments;
1646     *  StringBuffer sb=null;
1647     *  if(acontext!=null) sb=new StringBuffer();
1648     *  for(int j=0; j<ptr.length;j++){
1649     *  if(ptr[j]==null) break;
1650     *  System.err.println("Comment: "+new String(ptr[j], 0, ptr[j].length-1));
1651     *  if(sb!=null)sb.append(" "+new String(ptr[j], 0, ptr[j].length-1));
1652     *  }
1653     *  System.err.println("Bitstream is "+vi.channels+" channel, "+vi.rate+"Hz");
1654     *  System.err.println("Encoded by: "+new String(vc.vendor, 0, vc.vendor.length-1)+"\n");
1655     *  if(sb!=null)acontext.showStatus(sb.toString());
1656     *  }
1657     *  convsize=BUFSIZE/vi.channels;
1658     *  vd.synthesis_init(vi);
1659     *  vb.init(vd);
1660     *  double[][][] _pcm=new double[1][][];
1661     *  float[][][] _pcmf=new float[1][][];
1662     *  int[] _index=new int[vi.channels];
1663     *  getOutputLine(vi.channels, vi.rate);
1664     *  while(eos==0){
1665     *  while(eos==0){
1666     *  if(player!=me){
1667     *  /System.err.println("bye.");
1668     *  try{
1669     *  /outputLine.drain();
1670     *  /outputLine.stop();
1671     *  /outputLine.close();
1672     *  io.close();
1673     *  }
1674     *  catch(Exception ee){}
1675     *  return;
1676     *  }
1677     *  int result=oy.pageout(og);
1678     *  if(result==0)break; // need more data
1679     *  if(result==-1){ // missing or corrupt data at this page position
1680     *  /           System.err.println("Corrupt or missing data in io; continuing...");
1681     *  }
1682     *  else{
1683     *  os.pagein(og);
1684     *  while(true){
1685     *  result=os.packetout(op);
1686     *  if(result==0)break; // need more data
1687     *  if(result==-1){ // missing or corrupt data at this page position
1688     *  / no reason to complain; already complained above
1689     *  }
1690     *  else{
1691     *  / we have a packet.  Decode it
1692     *  int samples;
1693     *  if(vb.synthesis(op)==0){ // test for success!
1694     *  vd.synthesis_blockin(vb);
1695     *  }
1696     *  while((samples=vd.synthesis_pcmout(_pcmf, _index))>0){
1697     *  double[][] pcm=_pcm[0];
1698     *  float[][] pcmf=_pcmf[0];
1699     *  boolean clipflag=false;
1700     *  int bout=(samples<convsize?samples:convsize);
1701     *  / convert doubles to 16 bit signed ints (host order) and
1702     *  / interleave
1703     *  for(int i=0;i<vi.channels;i++){
1704     *  int ptr=i*2;
1705     *  /int ptr=i;
1706     *  int mono=_index[i];
1707     *  for(int j=0;j<bout;j++){
1708     *  int val=(int)(pcmf[i][mono+j]*32767.);
1709     *  if(val>32767){
1710     *  val=32767;
1711     *  clipflag=true;
1712     *  }
1713     *  if(val<-32768){
1714     *  val=-32768;
1715     *  clipflag=true;
1716     *  }
1717     *  if(val<0) val=val|0x8000;
1718     *  convbuffer[ptr]=(byte)(val);
1719     *  convbuffer[ptr+1]=(byte)(val>>>8);
1720     *  ptr+=2*(vi.channels);
1721     *  }
1722     *  }
1723     *  outputLine.write(convbuffer, 0, 2*vi.channels*bout);
1724     *  vd.synthesis_read(bout);
1725     *  }
1726     *  }
1727     *  }
1728     *  if(og.eos()!=0)eos=1;
1729     *  }
1730     *  }
1731     *  if(eos==0){
1732     *  index=oy.buffer(BUFSIZE);
1733     *  buffer=oy.data;
1734     *  try{  bytes=io.getByte(buffer,index,BUFSIZE); }
1735     *  catch(Exception e){
1736     *  System.err.println(e);
1737     *  return;
1738     *  }
1739     *  if(bytes==-1) break;
1740     *  oy.wrote(bytes);
1741     *  if(bytes==0)eos=1;
1742     *  }
1743     *  }
1744     *  os.clear();
1745     *  vb.clear();
1746     *  vd.clear();
1747     *  vi.clear();
1748     *  }
1749     *  oy.clear();
1750     *  /System.err.println("Done.");
1751     *  try {
1752     *  if(io!=null)io.close();
1753     *  }
1754     *  catch(Exception e) { }
1755     */
1756  }
1757
1758
1759  /**
1760   *  Description of the Method
1761   *
1762   * @param  is  Description of the Parameter
1763   * @return     Description of the Return Value
1764   */
1765  private String readline(InputStream is)
1766  {
1767    StringBuffer rtn = new StringBuffer();
1768    int temp;
1769    do
1770    {
1771      try
1772      {
1773        temp = is.read();
1774      }
1775      catch (Exception e)
1776      {
1777        return (null);
1778      }
1779      if (temp == -1)
1780      {
1781        return (null);
1782      }
1783      if (temp != 0 && temp != '\n')
1784      {
1785        rtn.append((char) temp);
1786      }
1787    } while (temp != '\n');
1788    return (rtn.toString());
1789  }
1790
1791
1792  /**
1793   *  Description of the Class
1794   *
1795   * @author    tgutwin
1796   */
1797  class UDPIO extends InputStream
1798  {
1799    /**  Description of the Field */
1800    InetAddress address;
1801    /**  Description of the Field */
1802    DatagramSocket socket = null;
1803    /**  Description of the Field */
1804    DatagramPacket sndpacket;
1805    /**  Description of the Field */
1806    DatagramPacket recpacket;
1807    /**  Description of the Field */
1808    byte[] buf = new byte[1024];
1809    //String host;
1810    /**  Description of the Field */
1811    int port;
1812    /**  Description of the Field */
1813    byte[] inbuffer = new byte[2048];
1814    /**  Description of the Field */
1815    byte[] outbuffer = new byte[1024];
1816    /**  Description of the Field */
1817    int instart = 0, inend = 0, outindex = 0;
1818
1819
1820    /**
1821     *  Constructor for the UDPIO object
1822     *
1823     * @param  port  Description of the Parameter
1824     */
1825    UDPIO(int port)
1826    {
1827      //this.host="192.168.1.2";
1828      this.port = port;
1829      try
1830      {
1831        socket = new DatagramSocket(port);
1832      }
1833      catch (Exception e)
1834      {
1835        System.err.println(e);
1836      }
1837      recpacket = new DatagramPacket(buf, 1024);
1838//    sndpacket=new DatagramPacket(outbuffer, 0, address, port);
1839    }
1840
1841
1842    /**
1843     *  Description of the Method
1844     *
1845     * @exception  java.io.IOException  Description of the Exception
1846     */
1847    public void close()
1848      throws java.io.IOException
1849    {
1850      socket.close();
1851    }
1852
1853
1854    /**
1855     *  Description of the Method
1856     *
1857     * @return                          Description of the Return Value
1858     * @exception  java.io.IOException  Description of the Exception
1859     */
1860    public int read()
1861      throws java.io.IOException
1862    {
1863      return 0;
1864    }
1865
1866
1867    /**
1868     *  Description of the Method
1869     *
1870     * @param  array                    Description of the Parameter
1871     * @param  begin                    Description of the Parameter
1872     * @param  length                   Description of the Parameter
1873     * @return                          Description of the Return Value
1874     * @exception  java.io.IOException  Description of the Exception
1875     */
1876    public int read(byte[] array, int begin, int length)
1877      throws java.io.IOException
1878    {
1879      return getByte(array, begin, length);
1880    }
1881
1882
1883    /**
1884     *  Sets the timeout attribute of the UDPIO object
1885     *
1886     * @param  i  The new timeout value
1887     */
1888    void setTimeout(int i)
1889    {
1890      try
1891      {
1892        socket.setSoTimeout(i);
1893      }
1894      catch (Exception e)
1895      {
1896        System.out.println(e);
1897      }
1898    }
1899
1900
1901    /**
1902     *  Gets the byte attribute of the UDPIO object
1903     *
1904     * @return                          The byte value
1905     * @exception  java.io.IOException  Description of the Exception
1906     */
1907    int getByte()
1908      throws java.io.IOException
1909    {
1910      if ((inend - instart) < 1)
1911      {
1912        read(1);
1913      }
1914      return inbuffer[instart++] & 0xff;
1915    }
1916
1917
1918    /**
1919     *  Gets the byte attribute of the UDPIO object
1920     *
1921     * @param  array                    Description of the Parameter
1922     * @return                          The byte value
1923     * @exception  java.io.IOException  Description of the Exception
1924     */
1925    int getByte(byte[] array)
1926      throws java.io.IOException
1927    {
1928      return getByte(array, 0, array.length);
1929    }
1930
1931
1932    /**
1933     *  Gets the byte attribute of the UDPIO object
1934     *
1935     * @param  array                    Description of the Parameter
1936     * @param  begin                    Description of the Parameter
1937     * @param  length                   Description of the Parameter
1938     * @return                          The byte value
1939     * @exception  java.io.IOException  Description of the Exception
1940     */
1941    int getByte(byte[] array, int begin, int length)
1942      throws java.io.IOException
1943    {
1944      int i = 0;
1945      int foo = begin;
1946      while (true)
1947      {
1948        if ((i = (inend - instart)) < length)
1949        {
1950          if (i != 0)
1951          {
1952            System.arraycopy(inbuffer, instart, array, begin, i);
1953            begin += i;
1954            length -= i;
1955            instart += i;
1956          }
1957          read(length);
1958          continue;
1959        }
1960        System.arraycopy(inbuffer, instart, array, begin, length);
1961        instart += length;
1962        break;
1963      }
1964      return begin + length - foo;
1965    }
1966
1967
1968    /**
1969     *  Gets the short attribute of the UDPIO object
1970     *
1971     * @return                          The short value
1972     * @exception  java.io.IOException  Description of the Exception
1973     */
1974    int getShort()
1975      throws java.io.IOException
1976    {
1977      if ((inend - instart) < 2)
1978      {
1979        read(2);
1980      }
1981      int s = 0;
1982      s = inbuffer[instart++] & 0xff;
1983      s = ((s << 8) & 0xffff) | (inbuffer[instart++] & 0xff);
1984      return s;
1985    }
1986
1987
1988    /**
1989     *  Gets the int attribute of the UDPIO object
1990     *
1991     * @return                          The int value
1992     * @exception  java.io.IOException  Description of the Exception
1993     */
1994    int getInt()
1995      throws java.io.IOException
1996    {
1997      if ((inend - instart) < 4)
1998      {
1999        read(4);
2000      }
2001      int i = 0;
2002      i = inbuffer[instart++] & 0xff;
2003      i = ((i << 8) & 0xffff) | (inbuffer[instart++] & 0xff);
2004      i = ((i << 8) & 0xffffff) | (inbuffer[instart++] & 0xff);
2005      i = (i << 8) | (inbuffer[instart++] & 0xff);
2006      return i;
2007    }
2008
2009
2010    /**
2011     *  Gets the pad attribute of the UDPIO object
2012     *
2013     * @param  n                        Description of the Parameter
2014     * @exception  java.io.IOException  Description of the Exception
2015     */
2016    void getPad(int n)
2017      throws java.io.IOException
2018    {
2019      int i;
2020      while (n > 0)
2021      {
2022        if ((i = inend - instart) < n)
2023        {
2024          n -= i;
2025          instart += i;
2026          read(n);
2027          continue;
2028        }
2029        instart += n;
2030        break;
2031      }
2032    }
2033
2034
2035    /**
2036     *  Description of the Method
2037     *
2038     * @param  n                        Description of the Parameter
2039     * @exception  java.io.IOException  Description of the Exception
2040     */
2041    void read(int n)
2042      throws java.io.IOException
2043    {
2044      if (n > inbuffer.length)
2045      {
2046        n = inbuffer.length;
2047      }
2048      instart = inend = 0;
2049      int i;
2050      while (true)
2051      {
2052        recpacket.setData(buf, 0, 1024);
2053        socket.receive(recpacket);
2054
2055        i = recpacket.getLength();
2056        System.arraycopy(recpacket.getData(), 0, inbuffer, inend, i);
2057        if (i == -1)
2058        {
2059          throw new java.io.IOException();
2060        }
2061        inend += i;
2062        break;
2063      }
2064    }
2065  }
2066}
2067