Adonis Lee Villamor
Adonis Lee Villamor

Reputation: 166

Create Anti-Phase / Inverse sound / noise cancel with audio byte data

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

Answers (2)

iggix
iggix

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

marko
marko

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

Related Questions