Wednesday, January 2, 2013

Respberry Pi with Shairport and USB Audio

Foreword

In previous article - AirTunes with Raspberry Pi, I've mentioned a way to use Raspberry Pi with Shairport for supporting AirTunes. Although there're quite a few articles on the Internet providing the guide to install Shairport on RPi, but I couldn't find a good doc mentioning how to use Shairport on Rpi with USB Audio. In this article, I'll try to explain how to intall Shairport and redirect the output to USB Audio.

Install Raspbian "Wheezy"

If you got a RPi in hand, the first thing to do is to download an OS image, and then load it on to the SD card. 

The official Raspbian "Wheezy" image is based on Debian, you can download it from here. You can choose any other OS package works on RPi, but it is better to star from the official OS package if you are new to RPi or even new to Linux based OS.

There are a few ways to make the SD card, since I'm using Mac OS X, I'll only explain how to write the image to an SD card by "dd" UNIX based utility.

Firstly, we need to open a terminal window, you can find a terminal application in /Applications/Utilities/Terminal. Since writing a image to SD card requires "root" permission, you'll need to "su"as root.
mac:~ user$ sudo -s
Password:
bash-3.2#
Insert the SD card in to a Mac. Since the Mac OS X will automatically "mount" the SD card to the system, and we can NOT write the image to a "mounted" disk, we have to "umount" it before writing the OS image to it.
bash-3.2# mount
/dev/disk0s2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
/dev/disk3s1 on /Volumes/NO NAME (msdos, local, nodev, nosuid, noowners)
bash-3.2#
As you can see, /dev/disk3 is the inserted SD card, and its first partition /dev/disk3s1 is mounted by Mac OS X automatically. Now we need to umount it.
bash-3.2# umount /dev/disk3s1
bash-3.2#
Also, we need to decompress the downloaded image:

bash-3.2# unzip 2012-12-16-wheezy-raspbian.zip
Archive: 2012-12-16-wheezy-raspbian.zip
inflating: 2012-12-16-wheezy-raspbian.img
bash-3.2#
Now, we are ready to write the image to SD card:
bash-3.2# dd if=2012-12-16-wheezy-raspbian.img of=/dev/disk3
It might take 20 minutes to complete, depends on the write speed of your SD card, so get a coffee and wait until it completes.

Once done, you can eject the SD card from your Mac and insert it on RPi, then plug in the power cord for booting up, you can then log in with user "pi" and password "raspberry".

Install Shairport

The following steps for installing the Shairport are mostly taken from here. However, we need to skip a few steps since we are going to use the USB Audio instead of the built-in HDMI or sound card analogue output.

After login, install the "git" utility

# sudo apt-get install git
Then install all other dependencies,
# sudo apt-get install build-essential libssl-dev libcrypt-openssl-rsa-perl libao-dev libio-socket-inet6-perl libwww-perl avahi-utils pkg-config
# sudo aptitude install libmodule-build-perl
# sudo git clone https://github.com/njh/perl-net-sdp.git perl-net-sdp
# cd perl-net-sdp
# perl Build.PL
#./Build
#./Build test
# sudo ./Build install
Get Shairport, then compile and install it
# Sudo git clone https://github.com/hendrikw82/shairport.git shairport
# cd shairport
# sudo make install

We'll need the Shairport running at RPi boot up,

# sudo cp shairport.init.sample /etc/init.d/shairport
# sudo insserv shairport

 Identify USB Audio Device

The audio devices on Linux is based on ALSA (Advanced Linux Sound Architecture), before redirecting the audio output through the USB audio device, we need to verify if our USB audio device can be recognized by ALSA.

pi@raspberrypi:~$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: Audio [PureAudio  USB HD Audio], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
pi@raspberrypi:~$
In above, the built-in sound card (BCM2835) is recognized as card 0/device0, and my PureAudio DDC 192 is recognized as card1/device0.

Before we redirect the output of Shairport, we need to make sure our USB audio device is not muted by the ALSA by default. If so, it must be unmuted first.
pi@raspberrypi:~$ sudo alsamixer
By pressing F6, we selected the sound card 1, i. e. our USB Audio device.


As we can see, there are two sub-devices under card 1, and one of these sub-devices is muted. (Pay attention to the "MM"). By using the UP/DOWN/LEFT/RIGHT keys, we can move the cursor to the sub-device, and by pressing "M" key, we toggled it to "unmute" state. ("MM" will become "00").


Once done, press ESC to exit and save the settings.

Redirect The Output of Shairport 

In previous sections, while we installing the Shairport, we have copied a sample startup script in to /etc/init.d, so that the Shairport will be started at boot time. However, since our goal is to play the audio via the USB audio device instead of the built-in sound card, we will need to modify the startup script to redirect Shairport's output to our USB audio device. You'll need a Text-Editor to complete the job. either vi, nano or joe will do the job. If you are not familiar with vi, you will need to install nano or joe. Here's an example for installing joe and edit the shairport startup script by joe.

pi@raspberrypi:~$ sudo apt-get install joe

Reading package lists... Done
Building dependency tree

Reading state information... Done

joe is already the newest version.

The following packages were automatically installed and are no longer required:
gstreamer0.10-pulseaudio libaudiofile1 libavformat53 libfaad2 libfftw3-3 libmms0 libmpcdec6 libmpdclient2 libshout3 libsystemd-daemon0
libwavpack1 libwebrtc-audio-processing-0 pulseaudio-utils rtkit

Use 'apt-get autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.

pi@raspberrypi:~$

pi@raspberrypi:~$ sudo joe /etc/init.d/shairport

Here's an example of modified startup script.
#!/bin/bash
#
# This starts and stops shairport
#
### BEGIN INIT INFO
# Provides: shairport
# Required-Start: $network
# Required-Stop:
# Short-Description: shairport - Airtunes emulator!
# Description: Airtunes emulator!
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO


# Source function library.

. /lib/lsb/init-functions

SPEAKER="MyShairport"
NAME=ShairPort
AODEV="plughw:1,0"
DAEMON="/usr/local/bin/shairport.pl"
PIDFILE=/var/run/$NAME.pid

#DAEMON_ARGS="-w $PIDFILE -a $NAME"
DAEMON_ARGS="-w $PIDFILE -a $SPEAKER --ao_devicename=$AODEV"

[ -x $binary ] || exit 0

RETVAL=0

start() {
    echo -n "Starting shairport: "
    start-stop-daemon --start --quiet --pidfile "$PIDFILE" \
                      --exec "$DAEMON" -b --oknodo -- $DAEMON_ARGS
    # Unmoute alsamixer
    amixer set -c 1 "PureAudio  Clock Selector" 127 unmute
    log_end_msg $?
At first, we can defined a "speaker name" for Shairport, so that you can identify it in iTunes.
SPEAKER=MyShairport
Secondly, we need to define an audio output device for redirecting the Shairport's output to the device. Since our USB audio device was identify as card 1/device 0 in previous section, we defined the AODEV as following:
AODEV="plughw:1,0"
Then we need to comment the original DEMON_ARGS by putting a "#" in front of the line, and recreated a new line to replace it.
#DAEMON_ARGS="-w $PIDFILE -a $NAME"
DAEMON_ARGS="-w $PIDFILE -a $SPEAKER --ao_devicename=$AODEV"

In the "start()" section, we need to add a line to "unmute" our USB audio device automatically at boot time instead of using alsamixer to toggle the setting everytime.
# Unmute alsamixer
amixer set -c 1 "PureAudio  Clock Selector" 127 unmute
Once completed, save the startup script, and then reboot the RPi. You should be able to airplay the music in your iTunes via the "MyShairport".
pi@raspberrypi:~/shairport$ sudo reboot

Troubleshooting

If you can see the "MyShairport" in your iTune, but cannot hear anything, try to log on RPi, and use alsamixer to check if it is muted again.

Caveat

According to the hardware architecture of Raspberry Pi, the network interface is connected to the processor via USB as well. Hence the efficiency of USB host driver will be critical for using USB audio device. Unfortunately, the USB host driver of RPi is not so efficient, even buggy. Don't be surprise if you found some unexpected clicks or pops while playing audio files through Shairport.

I've tested playing a WAV file on RPi locally with USB audio device, even without any network traffic, I'll still get some clicks and pops.

However, I do have successfully airplayed audio on RPi without any clicks/pops by using another USB audio device. The difference in between is the PCM output format of USB, the one without clicks/pops transferred the PCM to USB audio device using 24 bit on 3 bytes (24_3LE) for each audio sample, and the one with clicks/pops used 24 bit on 4 bytes (32_LE). It seems that by increasing 25% precent in the amount of data on the USB bus, it is more easier to get the clicks/pops. Hope the RPi foundation and BroadCom will come out with a solution for the USB host driver soon, or else, we may need to look for another solution.

On the other hand, with RPi's simplified hardware architecture with Async USB audio device, it sounds really beautiful and accurate. To me, it might be a prefect solution if RPi can get the USB issues resolved. I'll pay a little bit more patient for RPi for awhile unless I found another neat solution.



12 comments:

  1. 所以說 Ytsejam兄是以Mac to Respberry Pi to USB?
    若不先以Mac格式化SD會如何呢?

    ReplyDelete
  2. 我是以 Mac OS X 為例,介紹如何 SD Card 給 RPi 用。若您的 OS 是 windows ,RPi 官方網站上有提供程式可以使用。

    ReplyDelete
  3. Hi Ytsejam,

    Thank you so much for sharing! Your write-up is a true blessing to the non-tech-savvy audiophools (ie me), allowing us to have a bite of the Pi despite our lack of technical skills.

    Though the software side of the puzzle has been solved, the hardware aspects of things aren't quite so clear ... to some of us anyway :P

    I have no practical experience with asynchronous usb devices, so a lot of what you've discussed in the blog(s) seem foreign to me. Would you be so kind as to shed light on their mysterious ways?

    First off, what are the differences between async usb solutions? I heard that there are other chips capable of handling async usb, such as the CM6631 and TE8802. I'm particularly interested in the CM6631, as I remember reading somewhere that it can draw power from a discrete supply by design!

    Secondly, what are the most prominent factors affecting sound? Do the "hosts" that async usb devices attach to have a major impact on sound? Have you tried using the DDC 192 with your Mac? How does it compare to Pi?

    Thirdly, what are your views on commercial "Pi replacements"? With the release of EDO (enhanced digital output mod), the Squeezebox Touch is now capable of handling 24/192 async usb. It's obviously more pricey, but everything is handed to you on a silver platter, while being perfectly moddable. While it may or may not sound as good as the Pi, I'm pretty sure that its network doesn't screw with the usb ;)

    Thanks again for bearing with my newbie questions. Happy New Year, listen long and proper!

    ReplyDelete
  4. Hello Alex,

    I don't have experience regarding the CM6631 nor TE8022, the only thing I have is the XMOS based DDC 192. But I can share my tiny 2 cents on the Async USB.

    For other transfer types: such synchronous, adaptive, they rely on the data rate on the USB bus. And the host (your PC/Mac) controls how fast the audio data is transferred on the USB. Hence, the clock of USB "host" plays a critical role. For Async type, the USB host is responsible for transferring data to the USB device at a "free running" frequency. In other words, the audio sampling rate can be independent from USB bus clock. On USB device, received audio data is then be sent to DAC using its own clock. As long as the clock on the USB device is accurate enough, it is much more easier to minimize the jitter. We can take it as: the PCM audio data is being transferred to the USB device, and replayed by it with its own clock.

    What's the most prominent factor for the sound? IMHO, in the digital world, two terms: jitter and noise. Noise is something very tricky, if you didn't well control the noise, it will pass through the whole audio system. Especially when you are using cooper based media for connections between audio devices. For jitter, a lot of things may contribute to it, including the impedance of the circuit trace on the PCB. Unfortunately, we lived in a world with a lot of jitter and noise. To perfectly "replay" the audio, we'll need to pay a lot of attention on these two factors.

    So, why using RPi as the USB host? First, it is simple, it has only a few chips on it, to me, it is equivalent to less noise. Secondly, I can install "Shairport" on it for supporting AirTunes, so that I don't have to rebuild my music repository. Put it this way, the only reason for me to use RPi is to minimize the noise. For the jitter, since the audio data is actually "replayed" on the Async USB device, we can leave it to the USB device.

    In other words, with Async USB, the USB host is no longer important, the only thing you need to pay attention to is the noise, and maybe the functionalities (for ex. AirTunes).

    I did tried connecting my MBP to DDC 192, and compare it to my modified I2S AAE. Not bad, but it didn't convinced me to replace the current AAE with the Mac + Async USB solution. And i don't want to spend a lot of efforts on modifying the power supply for my Mac, since noise may be sourced from the USB host itself. in this case, no matter how good is the power supply, it just won't help.

    For RPi + Async USB, with the switching power supply, I realized the potential, since there's no much difference between it and my existing modified, carefully tuned AAE solution. After I replace the switching
    power of the RPi by a linear power supply, I was attracted, more detail, more harmonics and low-ends. Based on the observation, it implies that AAE has its own limitation (at least the digital), despite that I always want to get rid of its WiFi since that's a potential source of noise to me.

    For RPi replacement, the ideal solution to me is a simple host with separate LAN PHY and USB PHY. However, most of the hardware solutions today usually have excessive peripherals since people want do everything on it. Put it another way, I just want a simple knife, unfortunately most of the vendors are making swiss knifes in the market.

    I hope this helps.

    ReplyDelete
  5. Hi Ytsejam,

    (Sorry, just realized I got your id wrong in my last comment, how rude of me!)

    Thank you for taking the time to write such a detailed explanation, really appreciate it. I may have to steal that and put it in my new "Dummie's Guide to Hi-End File Audio" e-book for profitzz! j/k ;)

    Ahem.

    In all seriousness, your reasoning is sound. And from what I just learned, the Async USB is, in essence, a very cost effective reclocker for file-based audio systems. In my limited experience, a good reclocker significantly reduces the variance between transports, similar to how Async USB minimizes the impact of the host.

    I'm quite curious how a financially accessible setup like the Pi+"reclocker" (and a great dac ofc) stacks up against commercial offerings that DO cost an arm and leg, such as the legendary Linn Klimax DS.

    Either way, I find the reclocking Pi to be a very elegant solution, especially when compared to the ancient PC/sound card monstrosity popularized by the good folks over MyAV.

    I have to admit that I fell victim to the "way of PC" myself, no thanks to fellow inmates on Audio Asylum (the name "asylum" should've been warning enough, but I joined the crazy parade anyway). While tweaking can be fun to an extent, having near-infinite variables and being susceptible to all kinds of crap, are not.

    To put it in audiophool jargon, the old school PC transport is very jitter-prone, making it a rather poor base to build on. Sure, it's possible to erect a skyscraper on sand, but unless you're an Arab prince (or an M.D. with nothing better to do), why throw away time and money for no good reason?

    Speaking of which, there's a little drama happening over at myav as I type. Seems like people are fighting over some "NOS" HD5450 graphic card. I don't know if it's sad, hilarious, or both!

    Sorry about the babbling, I do remember having something constructive to say... Oh right! Thanks to your inspiration, I plan on ordering an Async USB device myself over the weekend. Still torn between several options, but I'm adamant in going Async USB. You'll be the first to know once the new toy arrives! :)

    On a side note, after consulting with several asylum inmates, it seems that most have migrated to low-power pc+Async USB. Of those who did, ALL agreed that Async USB is both sonically superior and more hassle-free. Looks like we're not alone!

    ReplyDelete
    Replies
    1. Hi Alex,

      To further clarify, IMHO, the magic of Async USB is not casted by the Async USB itself.
      Let's have a look at the history of digital audio.

      For digital audio system, since the analog audio signals are "sampled" at a specific frequency, i.e. clock.
      The device which generates the master clock determined the baseline for jitter.

      Take a look at CD player, the laser head reads the data from CD, and injects the master clock, then transfers the data via I2S to the built-in DAC chip, and converts the digital signal to analog, and then sends to the external amplifier. However, in those year, the built-in DAC might not be good enough, hence the DAC chip performance becomes a major factor of audio quality. That's why people were crazy about TDA1541 for a while, even today.

      Due to improvement on DAC chip, people wants a well designed, dedicate device to handle the digital to analog conversion. Because of this, we need a protocol to transfer the data and clock from the CD player to the DAC, that's why you see the S/PDIF or ASE/EBU interfaces.
      However, on the S/PDIF, since master clock (generated on the CD player) and data are encoded into a single steam, on the DAC side, we need to separate the data and use the PLL circuit to recover the master clock, then convert them into I2S, and send to the DAC chip.
      The problem is, the master clock is still determined by CD player, even we can recover the master clock perfectly, the quality of the master clock on the CD player set the limits already.
      That's why some people tried to use a better clock for CD player, or introduce some re-clock circuits on the DAC side.

      However, people found that since we converted the original I2S to S/PDIF and then recover it back, the impedance of the cable, a small capacitor on the signal path will introduce some difference for the clock, that's we called jitter.
      If the S/PDIF interface is not well designed between the CD player and the DAC, more jitter will be introduced.
      That's why some people tried to feed to I2S from CD player directly in to a DAC for bypassing the master clock recovery.
      (In this case, I usually connects the CDP and DAC via both I2S and S/PDIF, and fine tuned the S/PDIF until I couldn't find the difference in between, then I don't need the I2S connection anymore)

      Despite of the jitter, if we connects the CD player and DAC by cooper wire, noise will also traverse from one device to another, that introduces another factor - noise.

      (Part one)

      Delete
    2. (Part two)

      Swapping CDs is annoying (at least to me), so people replaces the CD player with a PC or Mac,
      from:

      CD Player --(S/PDIF, data+clock)--> DAC

      to:

      PC --(S/PDIF, data+clock)--> DAC

      Unfortunately, a PC is usually far more complex than a CD player, and it often lacks of a decent power supply.
      This implies more noise in the "data source" of digital system, and more factors may affects the jitter.
      And note that master clock is still generated at the PC side.
      Nobody knows how accurate the clock is on a PC (I'm not talking about the clock for the CPU or GPU, we need the accurate clock for the audio signal), if you have a decent sound card, it might not be a concern.
      But the problem is, on a PC, there are usually too many noise source. It's hard to deal with noise.
      I think this is the reason that I don't like the PC to DAC solution, there are too many variables.

      With AAE solution, I got the benefit from AirTunes. The audio data is sent from the Mac/PC to AAE, and the AAE "plays" the audio in S/PDIF or I2S format, and then sends to the DAC.
      Please note the definition of "playing", when I say "play", it means the audio data is encoded/incorporated with the clock.
      For AirTune, the PC/Mac only sends the audio data to AAE, it didn't send the clock.
      So the audio is actually being "played" on the AAE itself. Like this:

      PC --(AirTunes, data)--> AAE --(S/PDIF, data+clock)--> DAC

      For the AAE, the clock for I2S or S/PDIF is generated on the AAE itself. I can minimize the jitter or suppress the noise as possible, it hard to improve the clock of AAE.
      The first reason is, the clock on the AAE is running at 25MHz, which is for the processor of AAE, not for the audio.
      And the audio clock is synthesized by the AAE processor.
      Even I can replace the AAE's clock chip with a better one, I can't guarantee the audio clock is accurate enough.
      And this is the limitation of AAE.

      Let's move on to the Async USB. Put it simple, Async USB is just a "clock independent" protocol between your PC and the USB DAC.
      The audio data (note data only, no clock) is sent to the Async USB, and the audio data is being "played" on the USB device by a dedicate chip, such as XMOS processor, and then encoded/incorporated with the local master clock on the USB device depends on the audio sampling rate.
      If we built the Async USB into the DAC, it implies that the audio is being "played" and converted within the same device - DAC.

      The architecture becomes:
      PC --(Async USB, data) --> Async USB device --(I2S, data+clock)--> DAC

      Since the master clock is no longer generated by the PC in the Async USB architecture, jitter might not be a concern anymore.
      But since the Async USB device is powered by the PC, noise will pass through. If we replace the PC with a low noise, simpler architecture device, such a RPi, we actually minimize the noise.
      The only we need to do is to build a decent power supply for RPi to power up the RPi and Async USB device and minimize the noise.
      Isn't that simpler then using a PC? :)

      If we use the RPi with AirTunes, the architecture becomes:
      PC --(AirTunes, data)--> RPi --(Async USB, data) --> Async USB device --(I2S, data+clock)--> DAC

      When I firstly power the RPi with a linear power supply, and connect it to the USB Async DAC, I was shocked.
      Although RPi still has the USB driver issues, small pops and clicks may happend, but the sound quality is much better than my current fine tuned AAE transportation.
      Hope that BroadCom can get it resolved as soon as possible.

      Delete
  6. Hi Ytsejam,

    You see, I always "kind of" knew what was going on in the digital audio chain, but you described the processes in a very cohesive and easy-to-understand manner. I wish I had professors bothered to do that back in college!

    You are right, I made a mistake by oversimplifying the role of Async USB. It is not technically a "reclocking" device, though it does receive data and use its own clock for output. Thank you for the clarification, now I'm certain that the Async USB "IS" the master clock, which makes it even better!

    I fully agree that an RPi is a natural match for Async USB. The complexity of the PC transport is what eventually drove me away from it. I will not make the same mistake twice.

    Speaking of power supplies, have you considered modifying the actual RPi board? I'm certain that I will remove the micro USB connector and hardwire a quality linear supply to it, but despite reading the data sheets of the onboard LDOs, beyond that I don't have much of a clue. Any insight you'd like to share? :)

    My RPi should arrive soon, but I'll probably take a slightly difference approach. I would've gone Airplay - especially with your instructions available - except that it doesn't support high res playback in its current state. That would mean a significant amount of my HD-file collection would go to waste, and like most with Taiwanese parents, I was taught that one shouldn't let good stuff go to waste ;)

    Instead, Squeezelite would be installed on the RPi, turning it into the "ultimate squeezebox". It will replace the venerable SBT in my system. Absent the main sources of noise that plagues the original Squeezebox - namely display, wifi, and less than ideal onboard supply - the RPi is bound have superior sonic potential.

    The only thing that concerns me now is the USB/Ethernet issue. As stated, a good portion of my collection is 24/88 or higher, thus "popping" might be much worse in my application. I do remember that you mentioned an "FIQ" fix on Cynical Audio, can you please elaborate?

    Just a thought, have you considered eliminating SPDIF altogether?

    ReplyDelete
  7. Hello Alex,

    For RPi power, I use the "UCC regulator module" at 5V to power it. The reason for using the UCC is: I have it idle there for awhile, and it just fits the power requirement for my RPi experiment. I believe that a decent 7805 or LM317 based LDO will do a great job here. I think you don't need to remove the miniUSB connector, you can modify and type A USB socket, and solder it on to your LDO output.

    FIQ is a potential fix for the USB excessive interrupts for RPi. The FIQ code was added to the USB host driver with a knob, so that you can enable/disable it by configuration. As I know, it is now enabled by default in the "Raspbian".

    Regarding SPD/IF, interestingly, the best result I have today is not the RPi to Async USB DAC.
    Instead, My RPi goes to DDC 192, which converts USB data to SPD/IF (actually AES/EBU), and then to my DAC. Why? Theoretically, it shouldn't be the best, however, it is. I traced all the digital signal path on my system by oscilloscope before the signal entering the DAC chip. I found that's the best combination. And the listening result verified my electrical observation. Except for this, there are quite a few good reasons to keep the SPDIF,
    but let's leave the topic for the next chat.

    ReplyDelete
  8. Hi Ytsejam,

    What I meant to ask was whether you had plans to modify the power supply circuitry "on" the RPi board - the ones that further regulates the 5V input. I'll probably use a simple LT1086 as the 5V external supply for the time being. As for the connector, well, I simply try to avoid them whenever I can.

    Good to know that the fix is enabled by default.

    Just a wild guess, perhaps the Async USB implementation of the DDC 192 is better than the DAC? Speaking of oscilloscope measurements, I've been mightily impressed with that of my Gainclone. And I'm not even done rebuilding it! It sounds very impressive when done right.

    ReplyDelete
  9. Ytsejam兄請教一個問題
    你已以NAS來傳送音樂檔嗎

    ReplyDelete
  10. Yes, but the setup is a little bit different. All my music/video files are stored in iTunes via an iSCSI partition on the NAS. So it is not direct streaming from NAS to AAE/RPi, instead, iTunes "reads" the file from NAS via iSCSI, and streams the music from my Mac to AAE/RPi.

    ReplyDelete