Raspberry Pi -A New DIY'ers Digital Hub?

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
I made simple WAV file player on Raspberry Pi, using GPIO / external FIFO / 11.2896MHz clock / some 74HCs.
I'm not using any PLL or internal clock.

(1) read wav file into memory. (Free memory is around 180MB)
(2) set up GPIO, fill some 0 to FIFO
(3) generate I2S bit stream from PCM signal
(4) FIFO accepts 2 bits, LRCK and SDATA, 72V05 = 8K samples = 23msec. 72V06 is 16K samples.
(5) external 11.2896MHz and 74HCs "pulls" each I2S signal bit.

#makefile
CFLAGS += -O3
LDFLAGS += -lm
all: RaspWav01

to run
sudo ./RaspWav01 ../WAV/01.wav

reference
Code and Life – Benchmarking Raspberry Pi GPIO Speed
RPi Low-level peripherals - eLinux.org

maybe with some modification, I can make Raspberry Pi Jukebox.
(a) USB storage, has wav file folders, or NAS.
(b) LCD display
(c) Buttons; Play-Pause / Stop / Prev / Next, Next-folder, Prev-Folder
(d) program, auto start then wait loop for buttons, search folders

for 48 or 88.1 or 96kHz, more external logic and clock switching required.
I'm not sure GPIO is fast enough to process 96kHz bit by bit. if not fast enough, external parallel - serial (74HC165) or FPGA can help.
 

Attachments

  • Simple_GPIO_FIFO_I2S.PNG
    Simple_GPIO_FIFO_I2S.PNG
    129.3 KB · Views: 895
  • P8280114s.jpg
    P8280114s.jpg
    359.6 KB · Views: 838
  • RaspWav01.c.txt
    8.6 KB · Views: 79
I have one board here and one on the way.

but usb has that 'elephant' bug and so its a show-stopper for most of us until it gets fixed.

almost any way into the board or out of it is via usb. I think even networking is over usb (or behind usb). and usb is losing packets or something (I don't know the details). its not reliable yet.

until they fix that, I can't spend any time on this board. I hope they fix it soon!
 
I modified source code to use interrupt. more stable than before.
WriterThread does
(1) make bit stream from PCM
(2) output 1 bit
(3) check full flag. if full, stall until pin 24 rising edge. (more than half empty)

I think no more speed headroom for 88.1 or 96k PCM. when I add dummy GPIO read / wirte, buffer underrun occurs.
Maybe parallel GPIO output (8pins or more) and FPGA parallel - serial conversion can work for High resolution or DSD playback.

Anyway this method is very easy for your DIY, than dsPIC SDHC player.
The problems: Now I'm using CS4334, there are no "MUTE" pin so I can not stop glitch when FIFO is empty.

I'm waiting 'Humble Pi' add on for Raspberry Pi. when I get I will show more organized version.
 

Attachments

  • IntRaspWav01.c.txt
    12.3 KB · Views: 59
  • Simple_GPIO_FIFO_I2S(3).PNG
    Simple_GPIO_FIFO_I2S(3).PNG
    125.7 KB · Views: 748
revision 2.0

Posted Today..
Upcoming board revision | Raspberry Pi
"PCM_CLK, PCM_FS, PCM_DIN, PCM_DOUT" will be available at RPi Rev 2.0.
From reference manual
"In clock slave mode (CLKM=1), the PCM_CLK is an input, supplied by some external clock source."
So we can supply external master clock to Pi. it should be 22M/24M selectable by other GPIO.
PCM module has 64x32bit TX FIFO, Interrupt, and DMA.
 
DSD Playback by Raspberry Pi

I used the same board here,
https://sites.google.com/site/koonaudioprojects/dsd-playback-system

Now I try
DSD File Playback by Raspberry Pi -> (FTDI UM232H -> 22.4896MHz + FPGA DLP-HS-FPGA -> HC574) -> LPF -> small active speaker.

(1) Install
libusb-compat-0.1.4.tar.bz2
libftdi-0.20.tar.gz

(2) modify source code for libftdi
attached, read DSF file and make bit stream, then write to FTDI
#makefile
CFLAGS += -O3
LDFLAGS += -lm -lftdi
all: DSFPlayer01

(3) Hardware
I modified around UM232H for 5V power supply.
and I used CR LPF for DSD output to analog signal, then connected to active speaker.

(4) Playback
sudo ./DSFPlayer01 ../DSF/10.dsf

OK I success, it's easy:)

limitation: I can not read whole DSF file(over 200MB) into Raspberry Pi's memory(total 188MB), so now I only listen to leading 100MB.
Maybe multi-threading, (a) read and make bitstream (b) write to FTDI, with ping-pong buffering will work.
 

Attachments

  • P9050116.JPG
    P9050116.JPG
    644.5 KB · Views: 680
  • P9050117.JPG
    P9050117.JPG
    607.3 KB · Views: 665
  • DSFPlayer01.c.txt
    5.8 KB · Views: 76
DSD Playback by Raspberry Pi (2)

Attached, multi thread version
main() prepares buffer to send, then wait for signal
thread() copy buffer to local, then make signal, then send to FTDI

so main() is working to make next data while thread is writing to FTDI.
by top command, this program uses about 28% of CPU.
so DSD128 may work but DSD256 will spend too much CPU time.

I wonder FTDI's ARM driver can work faster than libftdi.
 

Attachments

  • DSFPlayer02.c.txt
    6.9 KB · Views: 73
I made simple WAV file player on Raspberry Pi, using GPIO / external FIFO / 11.2896MHz clock / some 74HCs.
I'm not using any PLL or internal clock.

wow, thats great work!
mpd or similar linux jukebox system that supports external playback "plugins" could be adjusted to use it as an output mechanism.


but usb has that 'elephant' bug and so its a show-stopper for most of us until it gets fixed.
At least the USB packet drop issue is partially fixable, with the addition of the fix at: https://github.com/raspberrypi/firmware/issues/19
.. although I've found this increases unreliability of the SDCARD.

I'm running with just "sdhci-bcm2708.missing_status=0" added to /boot/cmdline.txt and this seems OK.

.. still its been a lot of messing about to get it reliable, and it still leaves the power issues there, I've dropped drying to use a USB DAC and a wifi dongle at the same time.
 
wow, thats great work!
mpd or similar linux jukebox system that supports external playback "plugins" could be adjusted to use it as an output mechanism.

Hi thanks but this modification is useless for Rev2.0 board. omg.
Rev2.0 only requires external clock(22M/24M), HC08(and) + HC32(or) for clock selector, and HC574(reclock) for high quality I2S output.
 
...Rev2.0 only requires external clock(22M/24M), HC08(and) + HC32(or) for clock selector, and HC574(reclock) for high quality I2S output.
Great work indeed!
KOON3876, do you think the Rev 2.0 board will be capable of streaming 384KHz stereo WAV (ideally FLAC) read from an external USB hard drive?
If yes, pairing it with Ian's async FIFO could make a great digital source for a PCM DAC. My goal is to offline oversample with SoX or alike to 352.8/384KHz and stream it to a classic multibit DAC.

I was looking for .Net FEZ boards or Vinculum-II from FTDI to stream 384KHz from external USB drive but none can handle the needed data rate.
Thanks!
 
happy to be proved wrong there, it just seems unlikely given its still a shared port and if its pulling it in over wifi, processing then passing it out again, or the i2s goes out over another connection? I thought it was P5 as well? I was thinking more, like most problems with these things so far, that it would be a bus and/or driver bottleneck that would prevent it, not the CPU
 
384kHz = 384k*6=2.3MB/sec
I think it will work, for USB HDD or SSD read.

RPi PCM/I2S has Interrupt, DMA, TX FIFO.
large buffer, ex, 512KB + 512KB buffer will give 250msec cycle for audio playback application.
So I think it's possible, at least without driver, fully in application.
Sounds promising. I calculated a needed data rate of (384*64)/8=3.072MB/sec. Let's see what the real thing will be up for.
 
Hi vzs, 3.072MB/sec is PCM output data rate (32bit x 2)
384k/24bit wav file read rate, and on memory copy = 384k * 24bit / 8bit * 2ch = 2.3MB/sec.
This rate is required to read out wav file, it should be no problem when there are no other large transaction on USB.
I tested 100 x 1MB memcpy() on raspberry Pi, and result was 263MB/sec so memory bandwidth has no problem at all.

from BCM2385 ARM peripherals.pdf, so far I don't see any reason we can not use Raspberry Pi as a bit-perfect I2S player.
"It supports many classic PCM formats including I2S" "The length and polarity of the frame sync is fully programmable and it can be used as a standard frame sync signal, or as an L-R signal for I2S."
=> I2S OK

"Each channel can be between 8 and 32 bits wide"
=> up to 32bit

"The direction of the PCM_CLK and PCM_FS signals can be individually selected" "In clock slave mode (CLKM=1), the PCM_CLK is an input, supplied by some external clock source."
=> we can use external pure 11.2896MHz xtal, no PLL

"PCM Clock Disable: 1 = Disable the PCM Clock. This cleanly disables the PCM clock. This enables glitch free clock switching between an internal and an uncontrollable external clock. The PCM clock can be disabled, and then the clock source switched, and then the clock re- enabled."
=> ready for external clock selection(44.1k / 192k etc), with GPIO and external selector logic.

"CH1POS : Channel 1 Position. This sets the bit clock at which the first bit (MS bit) of channel 1 data occurs in the frame. 0 indicates the first clock of frame."
=> set this to 0x01 for I2S format
 
3.072MB/sec is PCM output data rate (32bit x 2)
384k/24bit wav file read rate, and on memory copy = 384k * 24bit / 8bit * 2ch = 2.3MB/sec.

...from BCM2385 ARM peripherals.pdf, so far I don't see any reason we can not use Raspberry Pi as a bit-perfect I2S player.
"It supports many classic PCM formats including I2S" "The length and polarity of the frame sync is fully programmable and it can be used as a standard frame sync signal, or as an L-R signal for I2S."
=> I2S OK

"Each channel can be between 8 and 32 bits wide"
=> up to 32bit

"The direction of the PCM_CLK and PCM_FS signals can be individually selected" "In clock slave mode (CLKM=1), the PCM_CLK is an input, supplied by some external clock source."
=> we can use external pure 11.2896MHz xtal, no PLL

"PCM Clock Disable: 1 = Disable the PCM Clock. This cleanly disables the PCM clock. This enables glitch free clock switching between an internal and an uncontrollable external clock. The PCM clock can be disabled, and then the clock source switched, and then the clock re- enabled."
=> ready for external clock selection(44.1k / 192k etc), with GPIO and external selector logic.

"CH1POS : Channel 1 Position. This sets the bit clock at which the first bit (MS bit) of channel 1 data occurs in the frame. 0 indicates the first clock of frame."
=> set this to 0x01 for I2S format
My calculation was wrong indeed.

The datasheet of BCM2385 doesn't say anything about the speed capabilities of the PCM interface. To support 352.8/384KHz the PCM should be capable to handle PCM_CLK of 24.576MHz. This would be nice to check before building an external interface board.

I don't quite understand how the external clock selection should work. What tells the external clock selector module what PCM clock speed to provide?
I'm thinking about a clock selector board that has two clocks 22.5792Mhz and 24.576Mhz, a clock divider with 74VHC393 and PCM clock speeds selectable for /1 /2 /4 /8 (through a BCD to decimal and some AND gates).
For this to work the RPi should specify the division factor and the frequency domain used 44.1k or 48k multiplies.
Am I thinking right or how can this be done in another way?

Thanks. Zsolt
 
...Further chewing upon the external clock board I came to conclusion that having Ian's FIFO I don't need an external clock board at all and will be OK with the jittery PLL clock generated by the RPi - provided that is not too jittery to over/under flow the FIFO.
Of course an external clock selection board plus some re-clocking would make the FIFO redundant but since it's here on my desk I would only need to hook it to the RPi.
 
for me it would need to be able to handle 90.3168/98.304MHz, while leaving the ESS OSF enabled. unless I use some sort of multiplier.

I think even with fifo we need to make sure its an audio frequency clock rate, the fifo will do what it can, but cant reverse aliasing
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.