Anyone know if it is possible to write an app that uses the Java Sound API on a system that doesn't actually have a hardware sound device?
I have some code I've written based on the API that manipulates some audio and plays the result but I am now trying to run this in a server environment, where the audio will be recorded to a file instead of played to line out.
The server I'm running on has no sound card, and I seem to be running into roadblocks with Java Sound not being able to allocate any lines if there is not a Mixer that supports it. (And with no hardware devices I'm getting no Mixers.)
Any info would be much appreciated -
thanks.
For linux you can use OSS Virtual Mixer, which will give you virtual sound channels.
On windows there are a few sound drivers that do this, one is Virtual Audio Cable, which, while not free, is about the cost of a sound card so it shouldn't be a hardship.
If neither of those work for you, it'll probably be easier to make your own Java sound library and replace the built in functionality than it would be to implement a sound card for your OS.
-Adam
All java needs are the drivers for a sound card. The JVM relies on the OS to handle direct hardware management, all JVM needs is a way to tell the OS that it wants a sound played (thus the driver).
Related
Could I use my M-AUDIO Fast Track Ultra as the audio interface in a Java MIDI plugin I'm writing? That virtual driver ASIO4ALL could be a nice way to go as well.
I will code a Live Performance MIDI Modifier, to enhance a keyboardist's level of control and complexity of MIDI-controlled effects. I've already begun a small proof-of-concept app that will get me going, but even when testing Oracle's own demo of the JavaSound API I notice some delay between the mouse input commands and the sound going. Whether this is caused by the way this app is constructed, I'll still find out, but I want to be sure I can deliver almost zero latency (20ms, as I get in my live performance host software). Have you guys found out anything relevant?
The only portable way to get a synthesizer is MidiSystem.getSynthesizer(), which gives you nothing but the default synthesizer, which outputs to some default audio device.
You would have to change the default audio output device of the JVM or of the OS.
The synthesizer has a fixed latency, which you can obtain with Synthesizer.getLatency().
The audio device will add its own latency.
I am trying to play audio stream which is read from audio playing in another system.
Could please tell me the how to read the audio bytes that our PC is playing audio currently.
Thanks & Regards
Yamini.
This has been asked many times. The answer is that the feature you want is not supported by Java (in fact, it is hard todo in any environment). This is not unreasonable since some operating systems don't support it. Your options are:
use a cable to connect the PCs output to its input. If you use an analog cable this will introduce some noise.
Use software like soundflower (mac only) to create a virtual cable.
Use JNI to access a low-level API for your system that can do it.
I'm writing a video recording program, and it's going quite well. I can record mic as well as video from the screen. However, I would also like to be able to obtain sounds from another Java program and then sync them with the video. Basically, record the audio as it is played by the other program.
Is there a way to accomplish this? I'm pretty new with sound, and have read a bit up on it. I think I need to set up a mixer, but I'm not sure if I can actually obtain sound from another Java program that way.
This is not possible with java sound, not because of any particular problem with java sound, but because not all audio APIs that java builds on support this feature. (Core audio on the mac for example, and ASIO on windows. Not sure about ALSA on linux, but I don't think it supports this either).
If you are on windows and want to write JNI/JNA code you can use PortAudio which supports this on one of the audio APIs (sorry I can't recall which one).
I'm trying to record/process some audio from three usb microphones with Java Sound on Snow Leopard (but can switch to Windows if it fixes things). Problem is, when I try to use the mixer that corresponds to the usb mic, Java Sound tells me that the line isn't supported. Specifically, it says this...
Available mixers:
Java Sound Audio Engine
USBMIC Serial# 041270067
Built-in Input Built-in Microphone
Soundflower (2ch)
Soundflower (16ch)
Exception in thread "AWT-EventQueue-0"
java.lang.IllegalArgumentException:
Line unsupported: interface
TargetDataLine supporting format
PCM_SIGNED 96000.0 Hz, 8 bit, stereo,
2 bytes/frame,
...when I ask it to select the USBMIC mixer:
Mixer mixer = AudioSystem.
getMixer(mixerInfo[1]);
I have tried matching the audio format to the exact specifications of the microphones (16-bit, 44100Hz, stereo) and it didn't make any difference.
The problem is cropping up here:
final TargetDataLine line = (TargetDataLine)
mixer.getLine(info);
It would seem that the mixer and the TargetDataLine don't like each other. Is there some way to get these two to 'match' and get along?
The microphones that I'm using are admittedly a bit strange. They were made to be used in a karaoke video game called SingStar. The mics themselves have standard mono line-in connectors that plug into a little hub (two to a hub) that converts them into a single male usb connector. Strangeness aside, though, they seem to work perfectly fine with Audacity as separate channels, so multichannel recording with them is clearly possible, just maybe not in Java.
I've also considered using a program like Soundflower that shares audio between different programs. However, I'm not sure this will work as I can't see how to make the USB mics inputs to Soundflower and then pipe them into a Java. A quick experiment showed me that I could record audio in Audacity from the mics, pipe it out through Soundflower, and then process in my Java program. Still, what I would like to do is have it all happen in real time in Java.
Anybody familiar with this kind of problem?
I think that a simple way to do this would be using Soundflower and Soundflowerbed.
I can't see how to make the USB mics inputs to Soundflower and then pipe them into a Java.
It sounds like you have Soundflower installed already. Soundflowerbed is found in the same disk image as Soundflower and is a menubar application. It lets you route sound between applications which don't have controls built in for selecting sound devices. Install that from the disk image and click it to run.
All of the following will be using my Echo Audiofire 4 but in principle should work on any audio device.
Using Soundflowerbed
Open Soundflower and tick the audio device you want to use under Soundflower (16ch). As I'm a new user I can't post images but they are linked below. If I get the bounty then I will edit the post to include the images inline.
From here you would use Soundflower (16ch) as your audio input device in Java sound.
Creating an aggregate audio device
An alternative way to solve this if that didn't work is to create an aggregate device. Open Applications > Utilities > Audio Midi Setup and click the plus sign to create a new aggregate device.
Tick the device that you want to aggregate. You only want your USBMIC (As I'm a new SO user I can only post two images per answer so the next two are linked here).
The key part which may be giving you trouble is the clock on the device. If you select the Mac as the clock source then that may be more stable.
If this still doesn't work then you could try adding the Mac built-in audio to the aggregate device and making it the master clock by right clicking on the device you want to be the master.
Other options
Finally, I haven't used this before but Pulse Audio (Google it, I can't insert more links in this post) might be a possible solution for mixing your audio streams together. It looks quite heavyweight though.
According to my research, especially threads like this, the microphone you are using is most likely causing the problem. The thread states that the microphone is even a problem when it comes to switching games, so I am guessing that it will be a problem when switching platforms, too.
My suggestion is - if you have not tried this already - to use a different microphone! Most microphones I have messed around with have special chip controllers that convert data into the data compatible for the game system. Being that you are using this on an operating system for the computer, you are probably getting some very odd effects that you wouldn't get on a game system like Playstation or others.
Hopefully this helps! Happy coding!
The AudioFormat doesn't match the TargetDataLine's supported format. I don't know if that was a typo or not but the Exception thrown says the TargetDataLine supports 8 bit audio and right below that you said you're using a 16 bit AudioFormat. It also supports up to 2 bytes per frame, how quickly and in what size chunks are you trying to read the data? Sorry if that doesn't help but I thought I'd point that out in case it was overlooked.
History & Situation:
I'm currently working on updating a Java application that was developed for a client several years ago (to run on WinXP) and is used for testing and training people with certain hearing impairments. Users who bought this application were provided with a particular USB sound device and headphones.
One of the most important requirements for this software is that the audio must be played to the user at specific decibel sound levels. Using the Java Sound API, the application was developed to dynamically adjust the Windows Volume to calculated levels (based on measurements made when calibrating the USB sound device & headphones during development).
Problem:
The application now needs to be upgraded to support Windows Vista and Windows 7, however due to Windows' new per-app sound architecture, I've been unable to find any way to access the Master/System volume using the Java Sound API.
The application's windows volume control alone doesn't cut it since it's relative to the system volume and there's no way to guarantee that the user will hear the output audio at a specific, known level.
Does anybody know if it is even possible to do this in Java and if so then how? If it's not possible, then can you give any guidance on what might be the simplest way to achieve it? (JNI and C perhaps - though I've never used JNI before... any gotchas to be aware of?)
If you run your application in Windows XP compatibility mode, it should work (it depends on how the Java Sound API interacts with the hardware volume).
If you want to use the Vista (and beyond) sound APIs, you want to look at the IAudioEndpointVolume API.
My guess is since you're using an USB device, your Java sound API does not access the correct channel.
You can have a look at how to adjust the master volume in Windows XP. I know you aren't working in XP but have a look at how to access specific Lines and Mixers on that link. You may have to experiment a bit to find the correct line and mixer combination, or offer your users a GUI that allows them to choose the correct line and mixer combination.
I've run applications that work with this method in Windows 7 so I doubt that it's an O compatibility issue.