To register and login, use your Google, Twitter, Facebook, LinkedIn, or OpenID credentials.

This is allowing us to stop most spam registrations. We've deleted most of the spam accounts that got through, and we're closely watching for more.

stream audio to PC via wifi

choonschoons Posts: 51
edited November 2012 in Pd Everywhere

Hi- I tried to search the forum for this, but nothing was returned. I'd like my libPd app to stream audio to my PC over my wireless network. I want to take advantage of the JBL/Paradigm sound system I have hooked up to my PC. I've seen apps like Twonky, AirPlay, and VLC Direct that do this, but I'd like to roll my own. I know bluetoot can do this but I'd prefer not to go that route. Before I reinvent the wheel, I wonder if someone has done this and can advise me how to set it up? Ideally, I'd like VLC player to handle play back on the PC side.

Answers

  • pbrinkmannpbrinkmann Posts: 685 ✭✭

    Interesting idea! I'm wondering whether streaming audio over wifi is the best solution here, though.

    Here's a random idea: Refactor your app into two components, a control component and a synthesis component. Have them communicate via netsend/netreceive (or maybe OSC if you're willing to tinker with externals). Now, in order to use the sound system attached to your PC, you can disable the synthesis component in your app, run the same patch in Pd on your PC, and route the control signals to the PC.

    That would give you the same effect, with fairly little work, unless you need sound input from the mic on your phone.

  • choonschoons Posts: 51

    oh and forgot to mention- this is on Android, but a general solution that works on either OS would be even better

  • choonschoons Posts: 51

    Hi Peter, thanks! Hmm yeah I see where you're going with that, but what I really really want is something that only requires me to point a media player on my PC at my phone somehow and just get all audio coming off the phone. I'm reading up on UPnP now, but was hoping someone had an easy solution ready to go.

  • pbrinkmannpbrinkmann Posts: 685 ✭✭

    In that case, the controller/synthesis split I suggested looks even more suitable. On your PC, you already have a perfectly good synthesis component. It's called Pd :)

  • pbrinkmannpbrinkmann Posts: 685 ✭✭

    Just to avoid confusion, my previous message was in response to your 2:00 message, not the one at 2:06.

    Anyway, if you're really determined to stream audio over wifi, you'll need to solve two problems. First, you'll need to find a library that works on Android. Assuming that that's available, you have to connect it to libpd. You probably won't be able to use the Android audio glue (i.e., PdAudio and PdService), but you can use the process methods of PdBase to render samples for the audio stream. Good luck!

  • choonschoons Posts: 51

    I ran across this interesting external called netsend~ that sends uncompressed audio over a LAN

    http://www.nullmedium.de/dev/netsend~/

    and this fork of it

    http://www.remu.fr/sound-delta/netsend~/

    I've never tried to get an external working in libPd, though I've read the threads here about it. Peter, or someone else savvy with externals, does this look like something promising to achieve what I want?

  • choonschoons Posts: 51
    edited December 2012

    OK I've been looking at how to send data from Android in UDP packets and think I understand that part. Looking now at the PdBase process methods it looks like I may be close to figuring this out.

    I'm not absolutely clear, however, on how to use those PdBase process methods. It seems to me that I need to be capturing the output from my [tabread4~] and routing it to the buffers mentioned in the PdBase.process, but I'm not clear on how to do that. I frequently listen for messages & values from Pd, but have never done so with an audio stream. How do I do that?

    [EDIT] - OK I see how PdBase.process works now. It grabs sample data internally from the main raw audio stream and stores it in the specified short[] outBuffer. A while loop can be used to continue calling the method as long as needed so it's best to put it in its own thread. I assume short[] was chosen to simplify things by having a single 16 bit value stored in a single index? And for using that data elsewhere that requires a byte[] it needs to be converted like:

    short nValue = outputBuffer[i];

    myByteArray[i] = (byte) (nValue & 0xFF);

    myByteArray[i+1] = (byte) ((nValue >>> 8) & 0xFF);

    where every sample value spans 2 indices (stride 2)

    So now I wonder is there a more direct way to just get the raw byte values instead of using a short[] and then converting to byte values? I haven't seen the source code for PdBase.process, but I suspect the data it initially grabs is byte data that is then converted to short data for convenience in graphing and such. If so, it's a waste of CPU cycles for my needs to then convert the values back to byte values.

  • pbrinkmannpbrinkmann Posts: 685 ✭✭

    The process method is overloaded to support three sample formats (short, float, double). The Android audio API expects 16-bit integers, and so that's what the Android components are using.

    About converting sample buffers to raw bytes, checkout the java.nio.ByteBuffer class. That one will let you create a buffer of raw bytes, which you can view as a ShortBuffer (resp. FloatBuffer or DoubleBuffer), which in turn you can view as a short (resp. float or double) array. No need to do any conversion by hand.

  • choonschoons Posts: 51

    OK, thanks, Peter. I didn't realize the Android audio API uses short values. So in any case the conversion is required to use Java's UDP packet classes.

    The process then to get the audio data sent to VLC on a PC over a wifi network looks to be: PdBase.process() -> byte[] + RTP header -> pack in UDP datagram packet -> send to network through datagram socket. Then on the PC side in VLC, Media -> Open Network Stream -> enter as rtsp://xxx.xxx.xxx.xxx:Port where the x's are your phone's IP address, and the Port is the port number you specify in the Java datagram code.

    I'll give this a try and report back how it works.

Sign In or Register to comment.