Reputation: 166
I am trying to check if it is possible to create Anti-noise or sound inverse using Java. (link)
I used the following format:
AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 16000, 16, 2, 4, 16000, false);
Once I captured a recording, I plan to use java's SourceDataLine class to write the stream out. Playing works normally. however as the goal is to "invert" the sound, I have to change the direction to it's opposite value (which as I have read so far is done by multiplying the value of the value by -1)
Since we use 16bit format, each 2 bytes in the stream counts as one value.
for(int i = 0; i < readBytes; i+=2)
{
inverse = (short)(data[i+1] << 8 | data[i] & 0xff);
System.out.println(inverse/100);
data[i] = (byte) (inverse & 0xff);
data[i+1] = (byte) ((inverse >> 8) & 0xff);
}
The code above reads each 2bytes, convert them into a 16bit short, reverse its value then insert it back to the same byte positions.
However, when this is runs,it sounds exactly like the original.
sourceLine.write(data, 0, readBytes);
Upvotes: 2
Views: 2875
Reputation: 21
Because the sound is the same, only with pressure value reversed. Your ear measures the absolute value of the pressure wave, that is the same for a reversed wave. Only when the wave and the reversed one are playing together their sum is 0, and only if played perfectly synchronized.
Upvotes: 2
Reputation: 9159
If a stream of samples is, X0.....Xn
, it's inverse (or anti phase, if you prefer) is -X0.....-Xn
.
Simply negating the inverse
will do the trick:
inverse = -((short)(data[i+1] << 8 | data[i] & 0xff));
The inverted audio will, of course, sound precisely like the original in absence of phase cancellation in free space.
Upvotes: 1