poly82
poly82

Reputation: 39

How to merge input and output audio to send another conferencer

I have changed my question message...

I have two streams with audio in Java. What I want is to combine these two audios into one OutputStream.

I've being searching and it seems that if you have both streams with the same audio format, and using PCM, you just need to do the following operation with the two byte arrays:

mixAudio[i] = (byte) ((audio1[i] + audio2[i]) >> 1);

However I am writing this into a file and I get a file without any audio.

Does anyone know how to combine two audios when I have the audios in two streams (not two audio files)?

Thank you in advance.

Upvotes: 1

Views: 220

Answers (1)

Scott Stensland
Scott Stensland

Reputation: 28305

decent quality audio consumes two bytes of data per sample per channel to give the audio curve a bit depth of 16 bits which gives your audio curve 2^16 distinct values when digitizing the analog audio curve ... knowing this you cannot do your adding while the data lives as simply bytes ... so to add together two channels you first need to get your audio out of its bytes and into a two byte integer ... then you need to pluck out of that two byte integer each of those two bytes one by one and stow into your output array

in pseudo code ( this puts into an integer two consecutive bytes of your audio array which represents one sample in your audio curve )

  • assign into a 16 bit integer value of your most significant byte

  • left shift this integer by 8 bits something like ( myint = myint << 8 )

  • bit level add to this integer your 2nd byte which is your least significant byte

Top Tip : after you have written code to populate one integer from two bytes then do the reverse namely convert a multi byte integer into two bytes in some array ... bonus points if you plot these integers so you can visualize your raw audio curve

To perform above you must know your endianness ( are you doing little endian or big endian ) which will determine the order of your bytes ... specifically since we now know each audio sample consumes two bytes (or more say for 24 bit audio ) the bytes myarray[i] and myarray[i + 1] are one audio sample however only after knowing your endianness will you realize which array element to use first when populating the above myint ... if none of this makes sense please invest time and effort to research notion of raw audio in PCM format

I highly encourage you to do all of above in your code at least once to appreciate what is happening inside some audio library which may do this for you

going back to your question instead of simply doing

mixAudio[i] = (byte) ((audio1[i] + audio2[i]) >> 1);

you should be doing something like this (untested especially regarding endianess)

twoByteAnswer = (byte) ((audio1[i] << 8) + audio1[i + 1]) + (audio2[i] << 8 + audio2[i + 1])) >> 1);

now you need to spread out your twoByteAnswer into two bytes of array mixAudio ... something like this (also untested)

mixAudio[i] =   twoByteAnswer >> 8  // throw away its least sig byte only using its most sig byte

mixAudio[i + 1] = twoByteAnswer && 0x0000FFFF // do a bit AND operator mask

Upvotes: 1

Related Questions