Hi Roy -
Ok, so you've got machine C which is receiving audio from machine B and sending audio to machine A.
Machine C operates in this context similar to what we call an Adapter in Design
Pattern language. That is, the program on machine C acts like an "interpreter" between the interfaces of two other programs that can't or don't talk directly to each other.
If you think of machine B as a data producer, and machine A as a data consumer, the threading model becomes real clear. Machine C's job is to block incoming data when it's buffer is full, and block outgoing data when it's buffer is empty. Outside of those conditions, allowing each side to push or pull data at their discretion would be the most effective use of threading in the middleware.
The format by which you send the data will be bytes no matter what you do. It's just a question of who does the byte-making. Using ByteArrayInputStream is efficient for sending and receiving, but you'll reassemble those bytes into their original data format, and that will cost something. It's the shape of the data itself that really determines the most effective method of transporting it.
------------------
Michael Ernest, co-author of:
The Complete Java 2 Certification Study Guide