Music module - best file formats

Hi again

I am testing the music module, and fully loaded Spider mainboard, it works, but the sound quality is not impressive, and I can hear that interrupts and serial communication disturbs and breaks up the sound.

I am thinking that the music module maybe has preferred sound formats and encodings that would help ensure good quality of the sounds, and avoid breakups.

I have tested mono 22050Hz, PCM, 16-bit, WAV - which works, but does not sound optimally.

Any ideas?

If you want good sound quality out of a music module you need to use RLP. NETMF is simply not fast enough to feed the VS1053 chip with enough data for smooth playback at good quality.

I suggest you start with examining RLP code from godfather89’s MP3 player.

I see that godfather89 did an excellent job. Very nice. I have been looking through the code, and finding the RLP extension he has made.

I think my fuses are going to pop if I throw myself into porting that to a generic music driver. Has anyone extracted the essential parts of the godfather solution?

@ njbuch - I’ve ported @ godfather’s RLP code to the Panda II, and fixed some bugs and added some enhancements (e.g., load plugin files from SD card, and EarSpeaker mode). I’m able to play FLAC files from the SD card without any problems, and while they are playing I am able to adjust volume, base, treble, and EarSpeaker settings without any glitches. I’m currently working on adding Internet streaming, but that’s a lot more complicated because I have to share the SPI bus, and because the Panda II has VERY little memory to work with.

Brilliant, is that something I can have a look at?

@ njbuch - Yes, absolutely. It’s too big to include in this post. I’ll publish it to the Code Share site in a couple of days.

2 Likes

Awesome, how much work do guesstimate that a Spider and a Cobra2 port will require?

@ njbuch - The original driver from @ godfather was written for the Cobra I, which is EMX, and I think is equivalent to the Spider. I modified the RLP code to use SSP0 instead of SSP1, and the GPIO pins were different. Here is a portion of the driver file:


//-------------------------------------
// VS1053 is connected to GPIO and SSP0 on PandaII
//
// DREQ				P0.0	(IO19) FEZ_Pin.Digital.Di4
// RESET			P0.1	(IO15) FEZ_Pin.Digital.Di7
// SCK				P0.15	(IO42) SPI.SPI_module.SPI1
// MISO				P0.17	(IO40) SPI.SPI_module.SPI1
// MOSI				P0.18	(IO41) SPI.SPI_module.SPI1
// XDCS				p1.30	(IO29) FEZ_Pin.Digital.An4
// XCS				P1.31	(IO32) FEZ_Pin.Digital.An5
// RED				P1.20	(IO25) FEZ_Pin.Digital.Di9
// GREEN			P1.21	(IO23) FEZ_Pin.Digital.Di8
//
 #define DREQ		(FIO0PIN & (1 << 0))
 #define RED_ON		FIO1SET = (1 << 20)
 #define RED_OFF		FIO1CLR = (1 << 20)
 #define GREEN_ON	FIO1SET = (1 << 21)
 #define GREEN_OFF	FIO1CLR = (1 << 21)
 #define SSP0_INT	10

static void initPorts()
{
	// VS1053 is connected to SSP0 on PandaII
	PINSEL0 &= ~((0x03 << 0));		// set DREQ as GPIO
	PINSEL0 &= ~((0x03 << 2));		// set RESET as GPIO
	PINSEL0 &= ~((0x03 << 30));		// set SCK as GPIO
	PINSEL1 &= ~((0x03 << 2));		// set MISO as GPIO
	PINSEL1 &= ~((0x03 << 4));		// set MOSI as GPIO
	PINSEL3 &= ~((0x03 << 28));		// set XDCS as GPIO
	PINSEL3 &= ~((0x03 << 30));		// set XCS as GPIO

	PINSEL0 |= ((0x02 << 30));		// set SCK as SSP0
	PINSEL1 |= ((0x02 << 2));		// set MISO as SSP0
	PINSEL1 |= ((0x02 << 4));		// set MOSI as SSP0

	FIO0DIR &= ~(1 << 0);			// set DREQ as input
	FIO0DIR |= (1 << 1);			// set RESET as output
	FIO1DIR |= (1 << 30);			// set XDCS as output
	FIO1DIR |= (1 << 31);			// set XCS as output
	FIO1DIR |= (1 << 20);			// set RED as output
	FIO1DIR |= (1 << 21);			// set GREEN as output
}

static void initSSP0()
{
	PCONP |= (1 << 21); // make sure power is on for SSP0
	
	SSP0CR0 = 0x07;		// set DSS data to 8-bit, Frame format SPI, CPOL = 0, CPHA = 0
	SSP0CPSR = 0x48;	// clock prescaler 72 -> 1MHz clock
	SSP0CR1 = 0x02;		// enable SSP0 in master mode, normal operation
	SSP0IMSC = 0x00;	// disable interrupts

	clearRxFifo();

	// install SSP0 interrupt
	RLPext->Interrupt.Install(SSP0_INT, ssp0_Interrupt, (void*)0);

	// enable interrupt
	RLPext->Interrupt.Enable(SSP0_INT);
}

Wonder if G400/Raptor adds enough speed to CLR; obviating the need for RLP?

@ Jeff - I was hoping that the Cerbuino Bee Net would be fast enough. If I can’t get everything working on a Panda II, including Internet streaming radio, then I was going to use a Cerbuino Net.

I believe that the Cerb family would not be an entirely good fit for this situation. We had a client that was working on using a Cobra II to power almost exactly what you are talking about, and with internet controls.

While the system acted fine for the most part, there were still audible hiccups along the way, especially when using the networking. While there was much more to his system than yours (threading etc) probably has, I would play it safe and just attempt it with the big guns,

With a Panda II project (doorbell/motion-sensor virtual dog) I tried a few dozen different sound encodings and finally decided on Ogg Vorbis (48000Hz, 16-bit PCM) Bit rate ranged between 75 kbps to 110 kbps. It sounded the best, given the compression ratios that I wanted for this project.

I wanted to maximize the compression without hurting the audio quality. (lower data throughput means less work for the system and smaller chance the system will be busy when we need more data from the SD card) And Ogg Vorbis has native support in the vs1053 (The Panda II has so little memory that did not waste any of it on downloading a decoder into the music chip.)

I am using 5-20 second clips from a SD card and the quality is very good (better than any doorbell you have ever heard, but not audiophile - weak link would be the $40 amp and ceiling speakers) .

@ James - Thanks. I think the Panda II is powerful enough to do what I want, but its limited RAM is making it almost impossible to load everything that I need to load. I’m going to continue trying, but if I can’t get it to work, I will probably switch to the Cerbuino Net. It would provide more speed and a lot more RAM, and combined with RLPLite, would hopefully do what I want.

@ eolson - Here is what I’m trying to accomplish with the Panda II:

I want a device in each room of my house that can do the following:
[ul]Communicate with a central server using cut-down version of MQTT protocol.
Play FLAC or MP3 files from SD card.
Play streaming radio from the Internet.
Monitor a motion detector and a door/window contact sensor.
Include an IR receiver for local control with a hand-held remote.[/ul]
I may end up doing a lot of this in RLP.

That sounds great. I got tired of squeezing every last byte from my panda (commenting out code so I could temporarily add debug statements). With my cobra II I can write much cleaner code, given the improved memory. My cobra project has pretty similar end goals, but I went for a centralized approach using my existing equipment:
Integration and custom control of a multi-zone amplifier (Nuvo), Pioneer A/V receiver, AppleTv, DirecTv box, and an Ademco Alarm system (interior & exterior motion & door sensors) Wall mounted control panels in each zone (Nuvo).
Streaming internet radio/pandora/sirius through the pioneer, but display and control in each room. MP3/Ogg/FLAC files from a wall mounted USB socket (played through the pioneer)
Sound clips from the music board go through the doorbell source to any music zone I need (for doorbell clips, messages, simulated dogs, wake-up alarm for sleepy teens, etc)
In other words, mostly getting thing to talk to each other and adding features on top.

@ eolson - Very impressive! I’ve been eyeing the Ademco security system for a long time, but it’s never had a very good Internet interface. There is this device for emulating a key panel, which could be connected to an NETMF device:

http://store.homeseer.com/store/Nutech-AD2USB-S2-Ademco-Vista-Panel-Interface-Series-2-P857C193.aspx

Big guns meaning RLP or big guns meaning Raptor?

I still think we should collect the great RLP nuggets already built and combine it into a new generic music module driver - avoiding hiccups and enabling stream-read from SD.

Most discussions in this thread are related to playing audio and probably covers most desires but one should realize that recording quality is limited by the low bandwidth of the SD card file write system.

Ok, it sounds like you have stuff in your sockets, and the question is: Do you need to go the RLP way to ensure good sound quality?

@ njbuch - Yes, I agree. Also it would be a waste to use a powerful board like the G400 just to play music.

I almost have my version of the RLP driver ready to publish to Code Share. This version does not play Internet radio streams. That will hopefully come in version 2. The current version can play MP3 and FLAC files from SD card on a Panda II smoothly, without glitches. Granted I’m not doing much else on the board when music is playing, so there may be issues if other application-level stuff is added.

The main reason I don’t have Internet radio streaming working yet, is because I can’t seem to get enough RAM to load all the assemblies needed, plus initialize the RLP music driver and managed WIZnet driver. I’ve tried everything I can think of, but I keep getting out of memory exceptions during startup. I will probably end up using the RLP SPI driver to also communicate with the WIZnet W5100 board (Connect shield), which means I need to write my own managed driver for this device. Not something I’m looking forward to.

No, note: I am not actually using the panda (now a cobra II) to play “music”. The wall mounted USB socket goes directly into the receiver’s USB socket and the receiver handles the music part. The music from the music board is limited to 5-30 second sound clips from the SD. I have a RS232 for the reciever, a RS232 for the multi-zone amp, USB-host for the alarm interface, and tcp for about everything else. I have not heard any problems playing the clips from the sound board. (I do get some data loss from the serial ports that I am still tracking down) If somebody rang the doorbell while I was syncing with a time server, I am sure I would hear a glitch… (that seems to lock up all the threads for some reason)