Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (115)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Voice Over IP (VOIP) without RTP or JMF  (Read 6058 times)
0 Members and 1 Guest are viewing this topic.
Offline dranonymous

Junior Member




Hoping to become a Java Titan someday!


« Posted 2004-07-14 15:36:46 »

I've used JMF on windows and was able to send audio via RTP.

I think it would be foolish to try and implement something of my own to simply send and receive audio.  I only need audio to go between 2 people, with somesort of PTT or VOX for the sending.

The hoops to go through installing JMF on windows and linux, then using RTP seems a bit much.

Any one have ideas or samples they can provide?  Is JMF my best hope?

Regards,
Aaron R>

Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #1 - Posted 2004-07-14 23:40:07 »

JMF sucks.  It is actually far easier to roll your own than to get it to work properly.

Check out the Ogg/Vorbis stuff... that should help you get most of the way.

Offline dranonymous

Junior Member




Hoping to become a Java Titan someday!


« Reply #2 - Posted 2004-07-15 01:58:16 »

Will do!

What about doing the capture though?  Once I've got the data, I'm probably 1/3 the way there.

ie get data, transport it, play it.

Regards,
Aaron R>
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #3 - Posted 2004-07-15 07:12:54 »

You can use javax.sound for capturing audio.
I found JSpeex very useful and easy for great sounding compression.

See http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=Sound;action=display;num=1089138785 for the code to decode using JSpeex and play the audio.
The code for the other way around (capture - encode) is about the same. I can post that too if you like when I get home.

Offline dranonymous

Junior Member




Hoping to become a Java Titan someday!


« Reply #4 - Posted 2004-07-16 18:26:46 »

Thanks alot for the code!  Yes, I would appreciate it if you posted the code for the other side as well.

Cheers!
Offline erikd

JGO Ninja


Medals: 16
Projects: 4
Exp: 14 years


Maximumisness


« Reply #5 - Posted 2004-07-18 17:25:01 »

Here it is:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

import org.xiph.speex.SpeexEncoder;
import org.xiph.speex.spi.SpeexEncoding;


public class AudioInputThread extends Thread {
      
      
      private AudioFileFormat.Type      targetType;
      private AudioInputStream            audioInputStream;
      private AudioStreamListener            listener;
      private TargetDataLine                  targetLine;
      private boolean running = false;
      
      private SpeexEncoder encoder;

      
      public AudioInputThread(AudioStreamListener listener) {
            
            AudioFormat      audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 16000.0F, 16, 1, 2, 16000.0F, false);
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
            TargetDataLine targetDataLine = null;
            encoder = new SpeexEncoder();
            encoder.init(1, SpeexEncoding.SPEEX_Q8.getQuality(), 16000, 1);
            
            try {
                  
                  targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
                  targetDataLine.open(audioFormat, 8192);
            } catch (LineUnavailableException e) {
                  
                  System.err.println("unable to get a recording line");
                  e.printStackTrace();
                  System.exit(1);
            }

            this.targetLine = targetDataLine;

            AudioFileFormat.Type targetType = AudioFileFormat.Type.WAVE;
            audioInputStream = new AudioInputStream(targetLine);

            this.listener = listener;
            
            start();
      }

      
      /**
       * Starts the recording. To accomplish this, (i) the line is started and
       * (ii) the thread is started.
       */

      public void start() {
            
            running = true;
            targetLine.start();
            super.start();
      }

      /**
       * Stops the recording.
       */

      private void closeLines() {
            
            targetLine.stop();
            targetLine.close();
            System.out.println("stopped");
      }
      
      
      public void stopInput() {
            running = false;
      }

      
      public void run() {
            
            byte[] buffer = new byte[640];
            
            while (running) {
                  
                  try {
                        
                        audioInputStream.read(buffer);
                        encoder.processData(buffer, 0, 640);
                        byte[] encoded = new byte[encoder.getProcessedDataByteSize()];
                        encoder.getProcessedData(encoded, 0);
                        listener.write(encoded);
                        
                  } catch (IOException e) {
                        e.printStackTrace();
                        running = false;
                  }
            }
            
            closeLines();
            System.out.println("Reading from mic stopped");
      }
}


It's not the most efficient code (you can easily get rid of the constant creating of new arrays in run() to avoid some garbage)

Offline dranonymous

Junior Member




Hoping to become a Java Titan someday!


« Reply #6 - Posted 2004-07-19 12:38:24 »

Hey thanks!  I'll see about playing with it a bit.  I won't be using it in a project for awhile, but when the time comes I'll be ready!
Offline parijsfr

Innocent Bystander




Java games rock!


« Reply #7 - Posted 2004-07-27 13:54:51 »

I saw the suggestion to use speex and am very interested.

I am trying to develop a VOIP application with more then 2 participants.
I am thinking about using speex, but this is only for coding (and decoding).
What if I want to stream.
I found an ietf draft to encapsulate JSpeex in rtp.
http://www.ietf.org/internet-drafts/draft-herlein-avt-rtp-speex-00.txt

Anybody implemented something like this yet?
or is there an alternative for RTP for streaming audio?

I need this urgently...

regards,
Frie
Offline dranonymous

Junior Member




Hoping to become a Java Titan someday!


« Reply #8 - Posted 2005-06-17 03:59:16 »

Can someone help me understand why my Mac is barfing on this?

1  
2  
3  
4  
5  
6  
7  
8  
9  
           AudioFormat      audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 16000.0F, 16, 1, 2, 16000.0F, false);
           DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
           TargetDataLine targetDataLine = null;
           encoder = new SpeexEncoder();
           encoder.init(1, SpeexEncoding.SPEEX_Q8.getQuality(), 16000, 1);
           
           try {
                 
                 targetDataLine = (TargetDataLine) AudioSystem.getLine(info);


I get the following exception -

Exception in thread "main" java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED, 16000.0 Hz, 16 bit, mono, big-endian, audio data is supported.


I tried changing the endian flag on the audio format, but it doesn't change anything.  Any other ideas?

Cheers,
Dr. A>
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #9 - Posted 2005-06-17 06:12:57 »

I have had this working on the mac OS X 10.4.1 with Java 1.5.0

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
        try {
            // Initialise Sound System
            AudioFormat audioFormat = new AudioFormat(RATE, 16, 1, true, true);
            DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);
            music = (Clip)AudioSystem.getLine(info);
            music.open(audioFormat, musicLoop, 0, musicLoop.length);
            music.loop(Clip.LOOP_CONTINUOUSLY);
            fire = (Clip)AudioSystem.getLine(info);
            fire.open(audioFormat, fireSound, 0, fireSound.length);
        } catch (Exception e) {
            e.printStackTrace(); // Display error, but keep going
        }

RATE = 16000f;
The differences are that I'm using the alternative constructor for AudioFormat, where I leave it to java to decide on the frame size and that I'm creating a Clip rather than a TargetDataLine.  Both Clip and TargetDataLine are subclasses of DataLine.

I'd try the alternative constructor for AudioFormat first.  If no joy, then there must be something unique to TargetDataLine, not inherited from DataLine which is causing the problem, in which case looking at the source might help.

/Edit Looking at this some more.  TargetDataLine is a source, while Clip is a sink.  This suggests the the microphone doesn't support the same data formats as the sound synthesiser.

/Edit I think it's the sample rate.  Browsing the web suggests 11025, 22050 and 44100 (CD sampling rate) as possibles.
Alan

Time flies like a bird. Fruit flies like a banana.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline dranonymous

Junior Member




Hoping to become a Java Titan someday!


« Reply #10 - Posted 2005-06-20 13:48:59 »

Alan -

Thanks for the info!  So far it seems to be the solution.  I'll post any new specifics if they come up.

Cheers,
Dr. A>
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

radar3301 (12 views)
2014-09-21 23:33:17

BurntPizza (30 views)
2014-09-21 02:42:18

BurntPizza (19 views)
2014-09-21 01:30:30

moogie (20 views)
2014-09-21 00:26:15

UprightPath (27 views)
2014-09-20 20:14:06

BurntPizza (31 views)
2014-09-19 03:14:18

Dwinin (48 views)
2014-09-12 09:08:26

Norakomi (74 views)
2014-09-10 13:57:51

TehJavaDev (102 views)
2014-09-10 06:39:09

Tekkerue (50 views)
2014-09-09 02:24:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!