openairplay / node_airtunes

node.js AirTunes v2 implementation: stream wirelessly to Apple audio devices.
BSD 2-Clause "Simplified" License
273 stars 84 forks source link

Running node_airtunes on Raspberry PI #6

Closed swissmanu closed 11 years ago

swissmanu commented 11 years ago

hi

i'm trying to use node_airtunes on a raspberry pi, running the latest raspbian “wheezy” build as operating system.

when executing one of your play_*.js examples, i hear only indefinable noise on my apple tv. doing the same on my mac works without any problem.

do you have any idea what could fix that problem? (compile options? c data types? ...) please find a log of my compile below.

thank you for any input! :) cheers, manu

make: Entering directory `/webapps/kaffeeundkuchen/node_modules/airtunes/build'
  CXX(target) Release/obj.target/airtunes/src/codec.o
In file included from ../src/../alac/ALACEncoder.h:29:0,
                 from ../src/codec.cc:15:
../src/../alac/ALACAudioTypes.h:64:32: warning: multi-character character constant [-Wmultichar]
../src/../alac/ALACAudioTypes.h:65:28: warning: multi-character character constant [-Wmultichar]
../src/../alac/ALACAudioTypes.h:154:22: warning: multi-character character constant [-Wmultichar]
../src/../alac/ALACAudioTypes.h:182:26: warning: multi-character character constant [-Wmultichar]
  CXX(target) Release/obj.target/airtunes/src/bindings.o
  CC(target) Release/obj.target/airtunes/alac/EndianPortable.o
  CC(target) Release/obj.target/airtunes/alac/ALACBitUtilities.o
  CXX(target) Release/obj.target/airtunes/alac/ALACEncoder.o
In file included from ../alac/ALACEncoder.h:29:0,
                 from ../alac/ALACEncoder.cpp:33:
../alac/ALACAudioTypes.h:64:32: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:65:28: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:154:22: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:182:26: warning: multi-character character constant [-Wmultichar]
../alac/ALACEncoder.cpp:48:36: warning: multi-character character constant [-Wmultichar]
../alac/ALACEncoder.cpp: In member function 'int32_t ALACEncoder::EncodeStereo(BitBuffer*, void*, uint32_t, uint32_t, uint32_t)':
../alac/ALACEncoder.cpp:279:13: warning: variable 'denShift' set but not used [-Wunused-but-set-variable]
../alac/ALACEncoder.cpp: In member function 'int32_t ALACEncoder::EncodeStereoFast(BitBuffer*, void*, uint32_t, uint32_t, uint32_t)':
../alac/ALACEncoder.cpp:559:13: warning: variable 'denShift' set but not used [-Wunused-but-set-variable]
  CC(target) Release/obj.target/airtunes/alac/ag_enc.o
In file included from ../alac/ag_enc.c:32:0:
../alac/ALACAudioTypes.h:64:32: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:65:28: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:154:22: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:182:26: warning: multi-character character constant [-Wmultichar]
  CC(target) Release/obj.target/airtunes/alac/ag_dec.o
In file included from ../alac/ag_dec.c:31:0:
../alac/ALACAudioTypes.h:64:32: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:65:28: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:154:22: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:182:26: warning: multi-character character constant [-Wmultichar]
  CC(target) Release/obj.target/airtunes/alac/dp_enc.o
  CC(target) Release/obj.target/airtunes/alac/matrix_enc.o
In file included from ../alac/matrix_enc.c:30:0:
../alac/ALACAudioTypes.h:64:32: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:65:28: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:154:22: warning: multi-character character constant [-Wmultichar]
../alac/ALACAudioTypes.h:182:26: warning: multi-character character constant [-Wmultichar]
  CC(target) Release/obj.target/airtunes/src/aes_utils.o
  CC(target) Release/obj.target/airtunes/src/base64.o
  SOLINK_MODULE(target) Release/obj.target/airtunes.node
  SOLINK_MODULE(target) Release/obj.target/airtunes.node: Finished
  COPY Release/airtunes.node
make: Leaving directory `/webapps/kaffeeundkuchen/node_modules/airtunes/build'
airtunes@0.1.3 node_modules/airtunes
└── async@0.1.18
lperrin commented 11 years ago

Hello Manuel,

I'll do my best to help you :) I'm suspecting a problem with the ALAC codec (proprietary lossless audio by Apple). I'm using the code provided by Apple, so not sure what could go wrong. Can you try the following:

swissmanu commented 11 years ago

hi lperrin

thank you for your fast response!

requireEncryption

here is the rtspConfig object:

{ audioLatency: NaN,
  requireEncryption: false,
  server_port: 51699,
  control_port: 49462,
  timing_port: 56695 }

udp_servers.js:95

uncommented, but no additional output here :-/ (not on the PI nor on my macbook)

tcpdump

there are a lot of udp frames with length 44 after a few others when running play_stdin on both test devices. i did not recognize any obvious anomaly when doing a rough comparison.

non of the participating devices (apple tv, macbook or pi) used the port 6000 as you described. seems that they negotiate some other ports during the handshake.

lperrin commented 11 years ago

OK, so there's no encryption, as suspected. The log in udp_servers.js would tell you about packets not parsed by the Apple TV (the AirPlay output can ask the server to retransmit packets via a separate UDP channel).

I'm a bit puzzled, can you post the .pcap files ?

Also, can you try to lower stream_latency in the config to 5ms (also try 10-20ms) ?

swissmanu commented 11 years ago

i played with the stream_latency without any improvement.

could there be a problem with the compilation of the ALAC codec on the PI? maybe some bit-order stuff or similar? just looked roughly over apples code, but it seems that they already handle different endian-modes.

please find the pcaps inside the following zipfile:

lperrin commented 11 years ago

As we suspected, everything is the same, except the ALAC outputs, which are different between the 2 dumps...

I'll work on a tool to dump the ALAC frames tomorrow to see if we can find something obvious. If you are willing to run more tests, there are other ALAC implementations that may not have this problem.

swissmanu commented 11 years ago

i already tried to search for another alac implementation... giving it a try tomorrow again and let you know.

thank you very much for your support! :+1:

lperrin commented 11 years ago

OK, I added some code in a "PI" branch in my fork (https://github.com/lperrin/node_airtunes/tree/pi). It will dump the PCM and ALAC frames.

Can you run the example (cat sample.pcm | node play_stdin.js ...) and send me the dump (at least the first few packets) ? I'll compare them with your pcap files.

swissmanu commented 11 years ago

you're fast! :) dump: http://dl.dropbox.com/u/6981682/framedump.dump

as far as i can see, the ALAC output from the PI differs from the encoded stuff on my mac. probably there is really a problem with compiling apples source on raspberry pi's.

lperrin commented 11 years ago

The first non-zero PCM packet gives me:

200040138981f8c1ff8000138981f8c1ff80000038ff0ae5f383000f816e04f8f8efff00ee2280f0

While I see this in your dump:

200040138981f8c1ff8000138981f8c1ff8000ff38ee5fb8300058c3883fe016eff8848ee300ff8022f0

Can you confirm that you get the same thing as me on your mac ? So far, I've found a lot of third-party ALAC decoders, but the only encoder is embedded in FFmpeg. It might not be easy to extract it.

Did you find anything else ?

swissmanu commented 11 years ago

so we have the following values:

// Mac lperring
200040138981f8c1ff8000138981f8c1ff80000038ff0ae5f383000f816e04f8f8efff00ee2280f0
// Mac swissmanu (10.8.2, macbook pro retina, 64bit):
200040138981f8c1ff8000138981f8c1ff8000ff38ee5fb8300058c3883fe016eff8848ee300ff8022f0
// PI:
200040138981f8c1ff8000138981f8c1ff800076613aff70ae5f783000f816e04f8f82f6e6578ee2280f0

each is different :-/ the only thing we can say, yours and the one from my mac are working.

just started some hacking to try using ffmpeg for encoding the packets data. maybe this could be one solution, maybe not since child_process.spawn relays on asynchronous callbacks. this makes it quite difficult to integrate with the present code.

-- EDIT -- maybe we could use only libavcodec instead of the "complete" ffmpeg for encoding: https://github.com/OptimalBits/navcodec

lperrin commented 11 years ago

I was thinking about extracting alacenc.c from libavcodec (https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/alacenc.c). I'll try to do it this week-end.

The file depends on several FFmpeg headers, but it seems possible to remove most of the dependencies.

swissmanu commented 11 years ago

that would make an even cleaner result, for sure. i'm curious about your solution already :)

lperrin commented 11 years ago

Hey I haven't forgotten about your issue, but I've been quite busy last week. I'll have more time this week-end to work on it.

swissmanu commented 11 years ago

no problem at all! same thing for me: quite busy with work... but thank you even more for your update! :-)

Am 06.02.2013 um 16:14 schrieb Laurent Perrin notifications@github.com:

Hey I haven't forgotten about your issue, but I've been quite busy last week. I'll have more time this week-end to work on it.

— Reply to this email directly or view it on GitHubhttps://github.com/radioline/node_airtunes/issues/6#issuecomment-13186393..

lperrin commented 11 years ago

good news ! @xdissent pushed a fix for your problem. Can you tell me if it works now ?

swissmanu commented 11 years ago

great! gonna give it a try as soon as possible! thx @xdissent :)

tomhulbert commented 11 years ago

Hi Guys,

I'm trying to get node-airtunes working on a Raspberry Pi too. However, I keep getting a build error when I try to install using npm. Get the following (just copied what seems to be the most relevant bits)...

... In file included from ../src/CAHostTimeBase.cpp:47:0: ../src/CAHostTimeBase.h:50:39: fatal error: CoreAudio/CoreAudioTypes.h: No such file or directory compilation terminated. make: *\ [Release/obj.target/airtunes/src/CAHostTimeBase.o] Error 1 make: Leaving directory `/usr/local/lib/node_modules/airtunes/build' gyp ERR! build error ...

Any ideas what is wrong or how I could get it working?

Would really appreciate some help.

Thanks,

Tom

lperrin commented 11 years ago

The problem is that npm is trying to compile Core Audio support, which is the sound API of OSX. Thing is, it should be disabled for other OSes. There is a conditional include in binding.gyp:

'conditions': [
    ['OS=="mac"', {
      'include_dirs+': '/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/sys',
      'sources': ['src/coreaudio.cc','src/CAHostTimeBase.cpp']
    }]
  ]

Can you try to tweak this file ?

lperrin commented 11 years ago

For some reason, github won't indent my comment :(

tomhulbert commented 11 years ago

Hi Laurent,

Thanks a lot for getting back to me so quickly!

I'm pretty new to node and npm. How can I tweak the binding.gyp file? I'm using npm to do the install.

Tom

lperrin commented 11 years ago

Fork the repo, edit binding.gyp to remove the conditional includes and type:

npm install git://github.com/tomhulbert/node_airtunes.git

If it works, then I'll have to figure out why your raspbarry PI pretends to be a Mac ;)

Laurent

On Saturday 27 April 2013 at 16:14, Tom Hulbert wrote:

Hi Laurent, Thanks a lot for getting back to me so quickly! I'm pretty new to node and npm. How can I tweak the binding.gyp file? I'm using npm to do the install.
Tom

— Reply to this email directly or view it on GitHub (https://github.com/radioline/node_airtunes/issues/6#issuecomment-17116757).

tomhulbert commented 11 years ago

Thanks, that's great. Just before I do...

This may be a really stupid thing to suggest. But... I'm doing the installation over ssh from my Mac. Is there any way this is related tot he problem?

lperrin commented 11 years ago

No it shouldn't be an issue.

tomhulbert commented 11 years ago

Ok. Will fork and try doing what you suggested. Thanks.

tomhulbert commented 11 years ago

It worked!

Thanks for your help.

swissmanu commented 11 years ago

just runned a short test streaming the sample.pcm from my pi to the appletv. works seamless now, awesome! :+1: thanks again for your help, and of course thanks @xdissent for the endianness fix :)