Microphone level in Java - java

I'm trying to access the level of the mic through Java.
I don't need to record anything, I just want to know a relative scale of sound level.
Is this possible in real-time?
If it's impossible, maybe this could work:
Start recording when the level is over a certain value, stop when the level drops under a certain level for a certain time
Recording bits of a quarter second and reading it's volume, and if it's under the threshold stop recording.
Thanks in advance

http://www.technogumbo.com/tutorials/Java-Microphone-Selection-And-Level-Monitoring/Java-Microphone-Selection-And-Level-Monitoring.php
Pretty good article on this. Helped me out a lot.
From what i can tell, this uses the root mean squared stuff talked about in #Nick's answer
Basically:
public int calculateRMSLevel(byte[] audioData)
{
long lSum = 0;
for(int i=0; i < audioData.length; i++)
lSum = lSum + audioData[i];
double dAvg = lSum / audioData.length;
double sumMeanSquare = 0d;
for(int j=0; j < audioData.length; j++)
sumMeanSquare += Math.pow(audioData[j] - dAvg, 2d);
double averageMeanSquare = sumMeanSquare / audioData.length;
return (int)(Math.pow(averageMeanSquare,0.5d) + 0.5);
}
and the usage:
int level = 0;
byte tempBuffer[] = new byte[6000];
stopCapture = false;
try {
while (!stopCapture) {
if (targetRecordLine.read(tempBuffer, 0, tempBuffer.length) > 0) {
level = calculateRMSLevel(tempBuffer);
}
}
targetRecordLine.close();
} catch (Exception e) {
System.out.println(e);
System.exit(0);
}

You can access microphones through the Sound API, but it won't give you a simple loudness level. You'll just have to capture the data and make your own decision about how loud it is.
http://download.oracle.com/javase/tutorial/sound/capturing.html
Recording implies saving the data, but here you can discard the data once you've finished determining its loudness.
The root mean squared method is a good way of calculating the amplitude of a section of wave data.
In answer to your comment, yes, you'd capture a short length of data (maybe just a few milliseconds worth) and calculate the amplitude of that. Repeat this periodically depending on how often you need updates. If you want to keep track of previous loudnesses and compare them, that's up to you - at this point it's just comparing numbers. You might use the average of recent loudnesses to calculate the ambient loudness of the room, so you can detect sudden increases in noise.
I don't know how much overhead there is in turning audio capture on and off, but you may be better off keeping the TargetDataLine open all the time, and just calculating the loudness when you need it. While the line is open you do need to keep calling read() on it though, otherwise the application will hang waiting for you to read data.

Related

How can I synchronise the playback of several ogg files in Java?

I have a song that has the different tracks in separate ogg files. I can play these ogg files together using Vorbis SPI to get the complete song. However I'm doing this by playing each ogg in a separate thread and I have no protection against the playback of each ogg file getting out of sync.
How would you go about ensuring they stay in sync. Ideally all tracks would pause if there was a delay reading any.
Once I've got this working I'll also be wanting to sync with graphics being displayed on screen.
I feel like what I need is some sort of time/location record so I know how far through each of the ogg playbacks have got to. I could then delay other threads until everything is back in sync.
I'm in early days so I'm happy to consider alternative playback libraries.
EDIT :
Following JimmyB's advice I'm now able to read into 4 byte buffers. I then add the buffers together using the following code :
for (int i = 0; i < byteLength; i++) {
data[0][i] = data[0][i];
for (int j = 1; j < numInputs; j++) {
data[0][i] += data[j][i];
}
}
This does work, but the output is distorted. I suspect clipping is occuring. How can I combine the sound bytes without this effect?
EDIT 2:
Dividing the byte by the number of inputs stops the clipping, but greatly reduces the quality of the playback.
EDIT 3:
I think I'm also losing sync between the tracks. My read method looks like :
// return true if there is more to come
private boolean fillBuffer(AudioInputStream audioInputStream, byte[] soundBytes) throws IOException {
byte empty = 0;
int offset = 0;
while (offset != soundBytes.length) {
int bytesRead;
try {
bytesRead = audioInputStream.read(soundBytes, offset, soundBytes.length - offset);
offset += bytesRead;
if (bytesRead == -1) {
Arrays.fill(soundBytes, offset, soundBytes.length, empty);
return false;
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.info("Boom");
}
}
return true;
}
It seems like the relationship between bytes read and time may not be linear? Perhaps that's in my head though.

Generate various data intensity on bus

I am trying to generate various types of data intensity on bus on a multiprocessor environment. Basically I need two patterns - almost negligible traffic on bus and very high traffic on bus. Initially I was thinking about accessing registers and not writing them back to cache/main memory to generate a low bus traffic. But I am not very sure about the idea. Besides I am doing the coding part in Java.
Any hints how to do this?
Architecture: x86_64
EDIT: I have the following code snippet.
mutex.lock();
try{
// Generate Bus traffic
}
finally{
mutex.unlock();
}
For each thread, I am trying to generate the traffic in the critical section.
Accessing registers generates zero traffic on the bus (unless you mean some CPU-internal bus). To generate maximum traffic on a CPU-memory bus, just read an array bigger than your biggest cache (typically L3 with a few megabytes). Make sure the read data gets actually used, so that DCE doesn't kick in.
long[] data = new long[1<<24]; // 8 * 16MB
volatile long blackhole;
void saturateBus() {
long sum = 0;
for (long x : data) sum += x;
blackhole = sum;
}
This should saturate your memory bus on a modern amd64 architecture as the loop can execute in 1 cycle per element. Assuming some unbelievably fast memory, you could need to unroll manually like this
long sum0 = 0, sum1 = 0;
for (int i=0; i<data.length; i+=2) { // assuming even `data.length`
sum0 += data[i+0];
sum1 += data[i+1];
}
blackhole = sum0 + sum1;

Slow Rendering in Mdpi and Ldpi android phones

Hi,
I am developing a game with the help of LibGDX and using Box2d in it. The problem is that when run my game on hdpi or tablets it run fine but in case of ldpi and mdpi the box2d bodies are not acting accordingly.
I think, it is taking much more time to render on those phones. So, how can I optimize my game for ldpi and mdpi phones.The values I am passing in world.step isworldbox.step(Gdx.graphics.getDeltaTime(), 10, 2000);
Thanks.
It is bad idea to use frame rate as time step. Box2D manual says:
A variable time step produces variable results, which makes it difficult to debug. So don't tie the time step to your frame rate (unless you really, really have to).
Also, you use too big values for velocity and position iterations. Box2D manual says:
The suggested iteration count for Box2D is 8 for velocity and 3 for position.
Try fixed time step and recomended iteration count like this:
float mAccomulated = 0;
float mTimeStep = 1.0f / 60.0f;
int mVelocityIterations = 8;
int mPositionIterations = 3;
void updatePhysicWorld()
{
float elapsed = Gdx.graphics.getDeltaTime();
// take into account remainder from previous step
elapsed += mAccomulated;
// prevent growing up of 'elapsed' on slow system
if (elapsed > 0.1) elapsed = 0.1;
float acc = 0;
// use all awailable time
for (acc = mTimeStep; acc < elapsed; acc += mTimeStep)
{
mWorld->Step(mTimeStep, mVelocityIterations, mPositionIterations);
mWorld->ClearForces();
}
// remember not used time
mAccomulated = elapsed - (acc - mTimeStep);
}

Is there an library in Java for emitting a certain frequency constantly?

Right, well. First time I'm actually using Java to fix a problem. I bought a new headphone set called Sennheiser 120 HD; but there's an issue.
If there isn't a constant emission of audio then the base for the headphones will eventually time out and turn off. The headphones are spammed with static, which is horrible on the ears. The solution to this for me currently is playing music 24/7 to prevent the static of death. Maybe I'm weird, but I don't want to listen to music 24/7.
I believe a workable solution for this would be to constantly emit a sound that the base can detect but I can't hear. The application would need to be efficient since it's running 24/7.
I've been doing some research, but I'm not that experienced with Java. I'm unable to find any library for emitting a certain frequency. Does anyone know of any?
It would be best to get the solution for this within 4 days, before my return policy at the store is no longer valid. Incase if this doesn't work.
I think you'll find that listening to a constant-frequency sound is painful on the ears. However, you could do it something like this, just using standard Java libraries:
AudioFormat format = new AudioFormat(44000f, 16, 1, true, false);
SourceDataLine line = (SourceDataLine)AudioSystem.getLine(new DataLine.Info(SourceDataLine.class, format));
line.open(format);
line.start();
double f = 440; // Hz
double t = 3; // seconds
byte[] buffer = new byte[(int)(format.getSampleRate() * t * 2 + .5)];
f *= Math.PI / format.getSampleRate();
for(int i = 0; i < buffer.length; i += 2) {
int value = (int)(32767 * Math.sin(i * f));
buffer[i + 1] = (byte)((value >> 8) & 0xFF);
buffer[i] = (byte)(value & 0xFF);
}
line.write(buffer, 0, buffer.length);
line.drain();

Code inside thread slower than outside thread..?

I'm trying to alter some code so it can work with multithreading. I stumbled upon a performance loss when putting a Runnable around some code.
For clarification: The original code, let's call it
//doSomething
got a Runnable around it like this:
Runnable r = new Runnable()
{
public void run()
{
//doSomething
}
}
Then I submit the runnable to a ChachedThreadPool ExecutorService. This is my first step towards multithreading this code, to see if the code runs as fast with one thread as the original code.
However, this is not the case. Where //doSomething executes in about 2 seconds, the Runnable executes in about 2.5 seconds. I need to mention that some other code, say, //doSomethingElse, inside a Runnable had no performance loss compared to the original //doSomethingElse.
My guess is that //doSomething has some operations that are not as fast when working in a Thread, but I don't know what it could be or what, in that aspect is the difference with //doSomethingElse.
Could it be the use of final int[]/float[] arrays that makes a Runnable so much slower? The //doSomethingElse code also used some finals, but //doSomething uses more. This is the only thing I could think of.
Unfortunately, the //doSomething code is quite long and out-of-context, but I will post it here anyway. For those who know the Mean Shift segmentation algorithm, this a part of the code where the mean shift vector is being calculated for each pixel. The for-loop
for(int i=0; i<L; i++)
runs through each pixel.
timer.start(); // this is where I start the timer
// Initialize mode table used for basin of attraction
char[] modeTable = new char [L]; // (L is a class property and is about 100,000)
Arrays.fill(modeTable, (char)0);
int[] pointList = new int [L];
// Allcocate memory for yk (current vector)
double[] yk = new double [lN]; // (lN is a final int, defined earlier)
// Allocate memory for Mh (mean shift vector)
double[] Mh = new double [lN];
int idxs2 = 0; int idxd2 = 0;
for (int i = 0; i < L; i++) {
// if a mode was already assigned to this data point
// then skip this point, otherwise proceed to
// find its mode by applying mean shift...
if (modeTable[i] == 1) {
continue;
}
// initialize point list...
int pointCount = 0;
// Assign window center (window centers are
// initialized by createLattice to be the point
// data[i])
idxs2 = i*lN;
for (int j=0; j<lN; j++)
yk[j] = sdata[idxs2+j]; // (sdata is an earlier defined final float[] of about 100,000 items)
// Calculate the mean shift vector using the lattice
/*****************************************************/
// Initialize mean shift vector
for (int j = 0; j < lN; j++) {
Mh[j] = 0;
}
double wsuml = 0;
double weight;
// find bucket of yk
int cBucket1 = (int) yk[0] + 1;
int cBucket2 = (int) yk[1] + 1;
int cBucket3 = (int) (yk[2] - sMinsFinal) + 1;
int cBucket = cBucket1 + nBuck1*(cBucket2 + nBuck2*cBucket3);
for (int j=0; j<27; j++) {
idxd2 = buckets[cBucket+bucNeigh[j]]; // (buckets is a final int[] of about 75,000 items)
// list parse, crt point is cHeadList
while (idxd2>=0) {
idxs2 = lN*idxd2;
// determine if inside search window
double el = sdata[idxs2+0]-yk[0];
double diff = el*el;
el = sdata[idxs2+1]-yk[1];
diff += el*el;
//...
idxd2 = slist[idxd2]; // (slist is a final int[] of about 100,000 items)
}
}
//...
}
timer.end(); // this is where I stop the timer.
There is more code, but the last while loop was where I first noticed the difference in performance.
Could anyone think of a reason why this code runs slower inside a Runnable than original?
Thanks.
Edit: The measured time is inside the code, so excluding startup of the thread.
All code always runs "inside a thread".
The slowdown you see is most likely caused by the overhead that multithreading adds. Try parallelizing different parts of your code - the tasks should neither be too large, nor too small. For example, you'd probably be better off running each of the outer loops as a separate task, rather than the innermost loops.
There is no single correct way to split up tasks, though, it all depends on how the data looks and what the target machine looks like (2 cores, 8 cores, 512 cores?).
Edit: What happens if you run the test repeatedly? E.g., if you do it like this:
Executor executor = ...;
for (int i = 0; i < 10; i++) {
final int lap = i;
Runnable r = new Runnable() {
public void run() {
long start = System.currentTimeMillis();
//doSomething
long duration = System.currentTimeMillis() - start;
System.out.printf("Lap %d: %d ms%n", lap, duration);
}
};
executor.execute(r);
}
Do you notice any difference in the results?
I personally do not see any reason for this. Any program has at least one thread. All threads are equal. All threads are created by default with medium priority (5). So, the code should show the same performance in both the main application thread and other thread that you open.
Are you sure you are measuring the time of "do something" and not the overall time that your program runs? I believe that you are measuring the time of operation together with the time that is required to create and start the thread.
When you create a new thread you always have an overhead. If you have a small piece of code, you may experience performance loss.
Once you have more code (bigger tasks) you make get a performance improvement by your parallelization (the code on the thread will not necessarily run faster, but you are doing two thing at once).
Just a detail: this decision of how big small can a task be so parallelizing it is still worth is a known topic in parallel computation :)
You haven't explained exactly how you are measuring the time taken. Clearly there are thread start-up costs but I infer that you are using some mechanism that ensures that these costs don't distort your picture.
Generally speaking when measuring performance it's easy to get mislead when measuring small pieces of work. I would be looking to get a run of at least 1,000 times longer, putting the whole thing in a loop or whatever.
Here the one different between the "No Thread" and "Threaded" cases is actually that you have gone from having one Thread (as has been pointed out you always have a thread) and two threads so now the JVM has to mediate between two threads. For this kind of work I can't see why that should make a difference, but it is a difference.
I would want to be using a good profiling tool to really dig into this.

Categories