Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

VS1053 breakout board

vs1053 audio stream mp3

  • Please log in to reply
13 replies to this topic

#1 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 11 October 2013 - 05:20 PM

Hi,

 

I'm working on a netduino plus 2 and vs1053 for a school project. The main idea of the project is to  stream mp3 audio from web. 

I succeed to request audio, but I'm completly block with the vs1053, I'm new with SPI and all stuff like this. 

For now, I read this datasheet : https://www.sparkfun.../SMD/vs1053.pdf

but i'm not sure of what I'm supposed to do with it. 

Any help will be appreciate.

 

Thanks.

P.S : I steel have a complete week to finish my project.



#2 Spoon

Spoon

    Member

  • Members
  • PipPip
  • 14 posts
  • LocationFort Collins, CO

Posted 11 October 2013 - 10:22 PM

You could try starting with this post.

http://forums.netdui...mini/?hl=vs1053

 

also try searching the forums for vs1053, you should find a good collection of results.



#3 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 12 October 2013 - 09:12 AM

Ok, thank you for the quick answer I will look at this :)

#4 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 12 October 2013 - 10:22 AM

My idea is pretty much the same than this topics but I don't use sd card for now. Anyway, it doesn't really help me, hanzibal describe his project but didn't say "how" he did it, and the only code spinnet I found are for an other component...

I continue to search ;) 



#5 Juzzer

Juzzer

    Advanced Member

  • Members
  • PipPipPip
  • 135 posts
  • LocationHertfordshire, UK

Posted 12 October 2013 - 02:07 PM

You can download the source code off codeplex for GHI's Gadgeteer music module as it uses the 1053.

#6 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 13 October 2013 - 12:17 PM

I finally end up with this resources : 

the second one is a c# implementation of the third resources. So i tried to use it but I don't succeed to read any data from the board...

This is my code :

using System;using System.IO;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware.Netduino;using System.Threading;using System.Diagnostics;using Microsoft.SPOT;namespace NetduinoApplication2{    public class VS1053    {        // GPIO ports:        private OutputPort _reset;        private InterruptPort _dreq;         private Cpu.Pin PinBsync = Pins.GPIO_PIN_D2;        private Cpu.Pin PinDreq = Pins.GPIO_PIN_D3;        private Cpu.Pin PinReset = Pins.GPIO_PIN_D6;  // NOTE: This doesn't map to an actual pin        private Cpu.Pin PinCs = Pins.GPIO_PIN_D9;         // Define SPI Configuration for VS1053 MP3 decoder:        private SPI.Configuration DataConfig;        private SPI.Configuration CmdConfig;        private SPI _spi;         // Registers:        private byte RegisterSciMode = 0x00;        private byte RegisterSciVol = 0x0B;        private byte RegisterSciClockf = 0x03;         public static readonly int BufferSize = 96;        private ushort SciMode = 0x880;  // SM_SDINEW (default) + SM_EARSPEAKER_HI         private bool _isInitialized;        private readonly byte[] ReadBuffer = new byte[BufferSize];        private readonly byte[] CmdBuffer = new byte[4];         private readonly AutoResetEvent AutoResetEvent = new AutoResetEvent(false);         public void Initialize() {            DataConfig = new SPI.Configuration(PinBsync, false, 0, 0, false, true, 3000, SPI.SPI_module.SPI1);            CmdConfig = new SPI.Configuration(PinCs, false, 0, 0, false, true, 3000, SPI.SPI_module.SPI1);                        Debug.Print("--- _isInitialized : " + _isInitialized.ToString());            if (_isInitialized)            {                Debug.Print("Shutdown !");                Shutdown();            }            _spi = new SPI(CmdConfig);            _reset = new OutputPort(PinReset, true);            _dreq = new InterruptPort(PinDreq, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);            _dreq.OnInterrupt += _dreq_OnInterrupt;             _isInitialized = true;             Reset();            var test = SciMode | (1 << 2);            var test2 = (ushort)test;            Debug.Print("--- set : " + test2.ToString("x") + " : " + test2.GetType());            CommandWrite(RegisterSciMode, test2);            var result = CommandRead(RegisterSciMode);            Debug.Print("--- read :");            foreach (byte b in result)            {                Debug.Print(b.ToString("x"));            }            //CommandWrite(RegisterSciClockf, 7 << 13);            //CommandWrite(RegisterSciVol, 0x2424);             //_spi.Config = DataConfig;        }         private void _dreq_OnInterrupt(uint port, uint state, DateTime time) {            if (state == 0)            {                AutoResetEvent.Set();            }            else            {                AutoResetEvent.WaitOne();            }            _dreq.ClearInterrupt();        }         private void Reset() {            Debug.Print("--- Start reset ---");            _reset.Write(false);            Thread.Sleep(1);            _reset.Write(true);            Thread.Sleep(1);            Debug.Print("--- Finish reset ---");        }         private void CommandWrite(byte address, ushort data) {            CmdBuffer[0] = 0x02;            CmdBuffer[1] = address;            CmdBuffer[2] = (byte)(data >> 8);            CmdBuffer[3] = (byte)data;             _spi.Write(CmdBuffer);        }         private byte[] CommandRead(byte address) {                        var buffer = new byte[4];                        CmdBuffer[0] = 0x03;            CmdBuffer[1] = address;            CmdBuffer[2] = 0;            CmdBuffer[3] = 0;            _spi.WriteRead(CmdBuffer, buffer, 0);             //ushort command = CmdBuffer[0];            //command <<= 8;            //command += CmdBuffer[1];            return buffer;        }        public void SetVolumePercent(int volume)        {            if (volume < 0 || volume > 100)                throw new ArgumentOutOfRangeException("volume");             SetVolumePercent(volume, volume);        }         public void SetVolumePercent(int leftChannel, int rightChannel) {            if (leftChannel < 0 || leftChannel > 100)                throw new ArgumentOutOfRangeException("leftChannel");            if (rightChannel < 0 || rightChannel > 100)                throw new ArgumentOutOfRangeException("rightChannel");             // TODO: Invert decibel value, divide by percent, call SetVolume(ushort leftChannel, ushort rightChannel)        }         public void SetVolume(ushort bothChannels) {            CommandWrite(RegisterSciVol, bothChannels);  // TODO: This doesn't work outside the Initialize() method        }         public void SetVolume(ushort leftChannel, ushort rightChannel)        {            SetVolume((ushort) (leftChannel*256 + rightChannel)); // TODO: Verify no loss of fidelity        }         public void SendData(FileStream fileStream)        {            var size = fileStream.Length - fileStream.Length % BufferSize;            for (var i = 0; i < size; i += BufferSize) {                fileStream.Read(ReadBuffer, 0, BufferSize);                 _spi.Write(ReadBuffer);            }        }         private void Shutdown() {            if (!_isInitialized) return;             Reset();             _spi.Dispose();            _reset.Dispose();            _dreq.Dispose();             _isInitialized = false;        }    }} 
using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino;namespace NetduinoApplication2{    public class Program    {        public static void Main()        {            VS1053 vs = new VS1053();            vs.Initialize();            //vs.SetVolume(0xFEFE);        }    }} 

And this is this output I got :

--- _isInitialized : False--- Start reset ------ Finish reset ------ set : 884 : System.UInt16--- read :00000000The thread '<No Name>' (0x1) has exited with code 0 (0x0).Done. 

I think I'm supposed to receive the exact same byte array that I send with CommandWrite, but I just receive 0...

Any Idea ?



#7 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 14 October 2013 - 09:58 AM

After some research, I found this in the vs1053 doc :

 

7.3 Data Request Pin DREQ

The DREQ pin/signal is used to signal if VS1053bs 2048-byte FIFO is capable of receiving data. If
DREQ is high, VS1053b can take at least 32 bytes of SDI data or one SCI command. DREQ is turned
low when the stream buffer is too full and for the duration of a SCI command.

 

I also found code example witch wait for the dreq pin goes to true :

private void CommandWrite(byte register, ushort data)        {            while (_dreq.Read() == false)            {                Debug.Print("- CommandWrite / _dreq : " + _dreq.Read().ToString());            }            _spi.Config = CmdConfig;            cmdBuffer[0] = CMD_WRITE;            cmdBuffer[1] = register;            cmdBuffer[2] = (byte)(data >> 8);            cmdBuffer[3] = (byte)data;            _spi.Write(cmdBuffer);        }

The result out put I get is : 

- CommandWrite / _dreq : FALSSE

 

And that's all, the code is block in the while loop...

 

The board is supposed to change the state of the dreq pin by herself, right ?



#8 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 14 October 2013 - 12:20 PM

Hi tuff!  

I haven't taken the time to look through your code but in the post below, you'll find code that is known to work perfectly well with Netduino mini and should work equally well with a NP2 after a few modifications.

 

http://forums.netdui...ge-2#entry35811

 

The code is stripped from stuff that are specific to my application and the remaining code is very simplistic which makes it fairly easy to follow and use as kind of a  ground to work from. For example, you'd have to add your existing code for fancy things like changing volume, etc. The code simply plays all songs from and SD card, one song after the other.

 

Also, there might be some reading of interest from that post on-wards.

 

Hope this helps!



#9 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 14 October 2013 - 12:27 PM

I remember  initially having quite some trouble with getting the chip to play. My problems turned out to be SPI related and at some point, I got a faulty GPIO pin connected to DREQ which was really hard to track down.

 

If you haven't already, take a look at this post:

http://forums.netdui...decoder-solved/

 

I posted on the VLSI support forums and among others, there's this one:

http://www.vsdsp-for....php?f=11&t=277

 

I've made many more posts on the vs1053b department of the VLSI forum. Please do search for my posts over there and I'm pretty sure you will find something useful:

http://www.vsdsp-for...id=298&sr=posts

 

Hope this helps!



#10 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 15 October 2013 - 02:25 PM

Ok so the error that I got come from a bad SPI configuration in my code. But I have an other problem now.

I can play a file on my sd card but the play rate is really too low,  it's like a "slow-motion" but for a song (RATE = 8000 Hz display in the visual output)

 

How can I speed it up ? (I'm sorry I don't understand perfectly your playstream function hanzibal ^^")



#11 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 17 October 2013 - 02:23 PM

I send order to my netduino card over network by my windows phone with an app I made. This app send to the netduino the song's name to play, On the netduino there is a socket server witch process the phone request and then send byte data to the vs1053.

With hanzibal's code, on the first song, i get this output :

RATE=8000 Hz (mono)

The music speed is really slow. And when I send a second order with another song :

RATE=44100 Hz (stereo)

But nothing is play...

 

I think i should have RATE=44100 Hz (stereo) at the first song to ear a clean sound, isn't it ?



#12 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 18 October 2013 - 03:43 PM

Sample rate and stereo/mono mode are properties of the song you are playing and so they depend on how each song was recorded. I added this info just for fun and it should not effect how well or poor a song is played. By the sound of it, you are suffering from poor transfer rate between the SD card (songs are on an SD card right?) and the vs1053b. If you look into my code, you can see that I crank up SPI speed as part of initialization. Have you incorporated that part into your code? Also I remember someone else had similar problems not all that long ago where I tried to help. Use google to search the forum for "vs1053b", the forum search does not work very well (or maybe it does now). Also, you cannot have Debug.Print in performance critical parts of your code, it will slow you down a great deal. I assume you don't use interrupts for DREQ since it too will add significant overhead. You must poll DREQ in a tight loop and then feed the chip fresh chunks of 32 bytes each as quickly as you can until DREQ changes again to indicate the buffer is now full and cannot accept any more data until the chip has consumed what you just fed it. Now, I did this with a mini which is considerably slower that an NP2 but I recall there were some problems mentioned in the thread I mentioned above.

#13 tuff

tuff

    New Member

  • Members
  • Pip
  • 8 posts

Posted 18 October 2013 - 05:05 PM

I tried without any Debug, I you were right, the speed rise up. But it's still to low compare to a normal play.

I use both of your sdcard class and vs1053 class, so I suppose I have the same than you...



#14 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 18 October 2013 - 07:23 PM

So, basically you're running the same s/w as me, then it ought to work especially on a faster uC. Well, at least one would think so but... Here's the thread I was thinking about in my last post: http://forums.netdui...ge-3#entry44437 It took me a while before I realized it's my own old thread but I believe it might be very relevant indeed from the post referred to and onwards, so read it carefully.





Also tagged with one or more of these keywords: vs1053, audio, stream, mp3

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.