If any of my fellow Xuggler users can tell me what I'm doing wrong, that would be awesome! I am doing the following:
Reading from ogv (ogg video)
Queueing the audio and video
Writing back to ogv
sounds simple right? The problem I am experiencing in my QueueMixer class is that the output file plays the audio 2x too fast, and no matter what I check or change with regards to pts it doesnt improve.
The eclipse project and all files being used are at this link:
http://dl.dropbox.com/u/7316897/paul-xuggled.zip
To run a test, compile and execute the StreamManager class; a test ogv file is included. Before anyone asks, yes I have to queue the data as it will be mixed with other data in a future version.
Audio has a sample rate. Make sure that you copy the sample rate from the input to the output, otherwise the system might use a default (like 44KHz while the original data was sampled at 22KHz which would create such an effect).
The fix is to multiply the sample count by two when extracting them from the ShortBuffer.
samples = new short[(int) audioSamples.getNumSamples() * 2];
audioSamples.getByteBuffer().asShortBuffer().get(samples);
Having half the samples causes the audio to play twice as fast.
Related
I'm trying to record from the microphone to a wav file as per this example. At the same time, I need to be able to test for input level/volume and send an alert if it's too low. I've tried what's described in this link and seems to work ok.
The issue comes when trying to record and read bytes at the same time using one TargetDataLine (bytes read for monitoring are being skipped for recording and vice-versa.
Another thing is that these are long processes (hours probably) so memory usage should be considered.
How should I proceed here? Any way to clone TargetDataLine? Can I buffer a number of bytes while writing them with AudioSystem.write()? Is there any other way to write to a .wav file without filling the system memory?
Thanks!
If you are using a TargetDataLine for capturing audio similar to the example given in the Java Tutorials, then you have access to a byte array called "data". You can loop through this array to test the volume level before outputting it.
To do the volume testing, you will have to convert the bytes to some sort of sensible PCM data. For example, if the format is 16-bit stereo little-endian, you might take two bytes and assemble to either a signed short or a signed, normalized float, and then test.
I apologize for not looking more closely at your examples before posting my "solution".
I'm going to suggest that you extend InputStream, making a customized version that also performs the volume test. Override the 'read' method so that it obtains the byte that it returns from the code you have that tests the volume. You'll have to modify the volume-testing code to work on a per-byte basis and to pass through the required byte.
You should then be able to use this extended InputStream as an argument when you create the AudioInputStream for the output-to-wav stage.
I've used this approach to save audio successfully via two data sources: once from an array that is populated beforehand, once from a streaming audio mix passing through a "mixer" I wrote to combine audio data sources. The latter would be more like what you need to do. I haven't done it from a microphone source, though. But the same approach should work, as far as I can tell.
I'm trying to write an application which adds some noises (or markers) to various parts of a Video Clip and trigger an action once a section (marker) been reached.
I think using technologies like Audio Stenography cannot help this purpose. As far I understood it, It hides a text value in unused sections of a WAV file and extract them from a file.
I also learned that any frequencies under 20 Hz and upper 20KHz cannot be heared by a human ear. Using a Audio Analysis library like musicg,
gave me an idea to recognize and encode those frequencies with some algorithms like FFT and trigger an action based on that encoded unhearable frequency.
That was all I could find out after a week of investigation and unfortunately don't know further and will appreciate if somebody have had a similar experience in this field and can help me.
I'd like to modify the audio input stream, the stream that would come
from my microphone.
I have looked through the java.sound package API, but did not entirely understand it,
nor how to modify direct sound input.
Does anyone here know how to do that, or know an API that is capable of doing it?
You want a mixture of things:
The Java Sound system: http://www.oracle.com/technetwork/java/index-139508.html
A trail for it: http://docs.oracle.com/javase/tutorial/sound/index.html
Using audio controls: http://docs.oracle.com/javase/1.5.0/docs/guide/sound/programmer_guide/chapter6.html (part of a wider set of documentation)
If you are able to give more information about what you want to do to the audio stream, it's likely we'll be able to give you more specific advice.
I've written a program that transmits a PCM stream from my pc to another pc or my android(using an AudioTrack). It uses java sound and takes the target and source lines from the Stereo Mix mixer. Everything technically works (sockets, mixers, lines, streams, buffers, etc.) but the output on the remote speakers is very static-y sounding. Even when there isn't sound coming through, there is a constant crackling sound. I've tested the programs on my phone and computer with the same result.
What can I do?
Thanks,
Bill
ps The code is pretty big, and kinda messy, but I can post it somewhere if you ask.
Typically the static means you're feeding incorrect data to the audio subsystem: given what you describe there's probably an error in the audio path, and I'd suspect you are either:
Experiencing some byte alignment issue when reading/transmitting/receiving the audio data from the source.
Inadvertently mixing your network stream with local loopback audio on the receiving end.
Feeding in invalid silence data (for sound subsystems that need to be constantly fed with audio data).
Not feeding in silence data when you should be.
I'm trying to write a function to dynamically create midi files on Android. Since there is no javax.sound.midi library I'm just writing the bytes out to file myself. I've found some great guides (see below) so I've been able to create multiple track midis. However I haven't been able to figure out how to switch instruments for any of the tracks so everythign is just using the default instrument.
I think from the documents I read the code I need is to "program change" followed by the program number.
What I've tried so far is writing the following out to a byteoutputstream array:
track.write((byte) 192); // 128 + 64
track.write((byte) x); // x is the instrument number between 1-128.
I've put this before the start of the note on/ note off track information, but it doesn't seem to do anything except make the midi take a long time to start. Am I on the right track here, or am I missing something? Any help is appreciated.
http://faydoc.tripod.com/formats/mid.htm
https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html
Finally figured it out. It was a just a simple thing, but I forgot to include track time before the program change. Once I added the 0 byte it worked.