Music

Hi All,
I’ve received my Fez Spider some days ago, and I’m tring to record audio from a music module.

I’m using the Ogg patch from http://www.tinyclr.com/codeshare/entry/269.

Second step, i connected the audio in to my iPhone to create an audio source.

This is what i get:

Many times my files are not readable. Some other times they are long just 2-3 seconds even if file lenght is 700-800K.
I’m not making any change to the code at moment, just using an usb pen to write files on and this works fine, no latency, no IO errors… nothing…
I’ve ispected files i receive… and the strage thing is that the OGG Vorbis header bytes are repeated more and more times in the file even where i espect to have payload bytes only.

I’ve tried with the GH Library from SDK (ver 4.1.1.0) an wih the version from Mike (see link above).
I’m going really mad about it:
My Music module is on port 6 of the Spider.

Any idea?

Regards and Respect to u all.

gianmaria
Italy

Hello,
same argument, stupid question, but i’m completely new with this hardware.

I’m using the MusicShield library from Micha, and this is written for Fez Panda 2.

So when the MusicShield class is instantiated it’s specific for this hardware:

//prototype
public MusicShield(SPI.SPI_module spi, FEZ_Pin.Digital dataCS, FEZ_Pin.Digital cmdCS, FEZ_Pin.Digital DREQ)

// in Micha example:
MusicShield musicShield = new MusicShield(SPI.SPI_module.SPI1, FEZ_Pin.Digital.An4, FEZ_Pin.Digital.An5, FEZ_Pin.Digital.Di4);

Now… i’ve a Fez Spider and my Music Module is on socket 6 (CSY), and Pins are different…

Where i can find the corrispondence? If i’ve connected te music modulo on socket 6… where are the corresponding pins:

SPI.SPI_module.SPI1
FEZ_Pin.Digital.An4
FEZ_Pin.Digital.An5
FEZ_Pin.Digital.Di4

anybody had same problem?

Please forgive me, but i’m absolutely new, even if my knowledge of .NET is very deep… my knowledge of hardware is near to 0.

Regards,
gianmaria

Hi Maria,

imho there are no dumb questions, only dumb answers…
Maybe this will be one ;).

You are using a FEZ Spider with the music module.
You want to use the driver for Panda 2 and a patch for that.

Why dont you use the Spider driver for the musicmodule?

Just hook the modules through visual studio up and use the musicModule Instance.

No need for other drivers or patches…

Just take a look at the tutorial pages in the wiki:

Have fun

Hello Weiti and Thank you so much for your answer.

Naturally the library was the first point where i watched too… but… the library from GH seems do nothing. When i stop the recording i just receive this messages repeated forever on the output window:

I have: 2771 samples
I have: 2771 samples
I have: 2771 samples
I have: 2771 samples
I have: 2771 samples

and nothing on the storage device…

I’ve stopped the recording after 20 seconds. The samples are never written to the microSD. Naturally the first thing i’ve done were to try to write something else ti the micro sd (a txt file) and everything goes ok. I think problem is in the library or in the driver, this part maybe is till not completed.

the main library seem to remain in this loop without exiting:


 while (samples > 0)
            {
                totalSamples = samples > 512 ? 512 : samples;

                ReadData(totalSamples);
                if (m_recordingStream != null)
                    m_recordingStream.Write(m_recordingBuffer, 0, totalSamples << 1);

                Debug.Print("I have: " + samples.ToString() + " samples");

                samples = CommandRead(SCI_HDAT1);
            }

The tutorial you are pointing to is incomplete as well…cause on recording part you can read… “Tutorial too soon to come…”.

Our main application require audio recording and streaming of recorded files over socket. the socket transimission is ready… but if we cant record audio this object is useless for our applications…
My doubt are on the OGG patch too… but if it worked for Miche it have to work for us too cause it’s just an init for the DSP (VLSI 1053).

If possible we will ask for payed support on this, cause the platform is very interesting and easy to use and in our company 50% of peole are .net capable.

Regards,
gianmaria
italy

1 Like

Hi all,
some news:

  1. Library from GHI SDK seems not to produce any file on stream you pass to the RecordOggVorbis function.

  2. Official library from CodePlex, if used “as is”, is completely useless cause recording buffers are never filled with data. If you want to use, must uncomment code. My working copy i can send if you ask, i’m tring attach to this message but it’s not possible.

  3. OGG Patches, must be loaded naturally, and i found it with important documentation here:

http://www.vlsi.fi/en/support/software/vs10xxapplications.html
most interesting part is here: http://www.vlsi.fi/fileadmin/software/VS10XX/vs1053-vorbis-encoder-170b.zip

At moment i tested the venc08k1q05 and venc16k1q05. With the first one audio were recorder, poor quality, but recorded, very similar to phone quality.
With the second one 16K, recording quality is really good but many samples were lost, and pieces of the recording are missing… it jumps while playng (with winamp on pc).

Maybe this things can help someone… at least i hope… and feel free to correct things i wrote or if you discover more let me know. I will continue to work on the lost samples problem. Dont think this is about the storage device speed… but it can be…

Ciao,
Gianmaria
italy

We are working on this. We see the problem and trying to find a solution. So far, we do not know why.

We welcome any input from those who have the module and can help.

Maybe a producer->consumer problem on SPI bus? But it is 3.5Mbit/s capable right? Same if writing on the SD, cause it is fast enough and anyway if problem is on the writing step this can be easly handled with some buffers.
My impression is that samples are lost in the process of reading from the DSP registers. tomorrow i will debug (try) some of this reading to see if all samples prodeced bt the module are captured and stored.

ciao,
Gianmaria

ps: forgive my poor english

It seem to work fine on lower rates. Guessing SPI drivers are too slow. Native RLP should fix it or faster hardware.

Still trying.

Yes,
cause i’m tring to optimize code on all used libraries (SPI, Music etc…) and problem seem to remain. Anyway this is an old matter:

http://www.tinyclr.com/forum/topic?id=3674&page=2

Tomorrow morning i will try RPL (00:09 AM here now).

Let me know if you get something working…

cheers,
Gianmaria

Hi,

It is related to performance. You can use RLP and it should be fine.
If the quality is not important in your project, you can use the patch file venc16k1q00.plg and don’t use SPI busy pin. This makes SPI to write/read faster.


           // Set up our SPI 
            m_dataConfig = new SPI.Configuration(socket.CpuPins[5], false, 0, 0, false, true, 3000, socket.SPIModule);
            m_cmdConfig = new SPI.Configuration(socket.CpuPins[6], false, 0, 0, false, true, 3000, socket.SPIModule);

For the file venc16k1q00.plg, you can download from here:
http://www.vlsi.fi/en/support/software/vs10xxapplications.html

16K can be enoght… how to remove the the SPI busy pin? Can you show me the part of code to edit?

Regards,
Gianmaria

Ok… sorry… i didnt seen the second part of the message… i will try immediatly.

Gianmaria

Firstly go to this: http://wiki.tinyclr.com/index.php?title=Gadgeteer_Driver_Modification
and learn how to modify a module source code.

Then you have Music.cs in project. Modify on Music contructor:


        // Note: A constructor summary is auto-generated by the doc builder.
        /// <summary></summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        public Music(int socketNumber)
        {
            // This finds the Socket instance from the user-specified socket number.  
            // This will generate user-friendly error messages if the socket is invalid.
            // If there is more than one socket on this module, then instead of "null" for the last parameter, 
            // put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
            Socket socket = Socket.GetSocket(socketNumber, true, this, null);

            socket.EnsureTypeIsSupported(new char[] { 'S' }, this);

            // Set up our SPI 
            m_dataConfig = new SPI.Configuration(socket.CpuPins[5], false, 0, 0, false, true, 3000, socket.SPIModule);
            m_cmdConfig = new SPI.Configuration(socket.CpuPins[6], false, 0, 0, false, true, 3000, socket.SPIModule);
            m_dreq = new InputPort(socket.CpuPins[3], false, Port.ResistorMode.PullUp);
            
            m_SPI = new SPI(m_dataConfig);

            Reset();

            CommandWrite(SCI_MODE, SM_SDINEW);
            CommandWrite(SCI_CLOCKF, 0xa000);
            CommandWrite(SCI_VOL, 0x0101);  // highest volume -1

            if (CommandRead(SCI_VOL) != (0x0101))
            {
                throw new Exception("Failed to initialize MP3 Decoder.");
            }

            SetVolume(200, 200);

            // This creates an GTI.InterruptInput interface. The interfaces under the GTI namespace provide easy ways to build common modules.
            // This also generates user-friendly error messages automatically, e.g. if the user chooses a socket incompatible with an interrupt input.
            //this.input = new GTI.InterruptInput(socket, GT.Socket.Pin.Three, GTI.GlitchFilterMode.On, GTI.ResistorMode.PullUp, GTI.InterruptMode.RisingAndFallingEdge, this);

            // This registers a handler for the interrupt event of the interrupt input (which is below)
            //this.input.Interrupt += new GTI.InterruptInput.InterruptEventHandler(this._input_Interrupt);
        }

Then go to


private void RecordOggVorbisThreadFunction()
{
           Reset();

            SetVolume(255, 255);
            ..........................
             while (!stopRecording)
            {
                if (m_stopRecordingRequested && !stopRecordingRequestInProgress)
                {
                    CommandWrite(SCI_AICTRL3, 0x0001);
                    m_stopRecordingRequested = false;
                    stopRecordingRequestInProgress = true;
                }

                if (stopRecordingRequestInProgress)
                {
                    stopRecording = ((CommandRead(SCI_AICTRL3) & 0x0002) != 0);
                }

                samples = CommandRead(SCI_HDAT1);
                if (samples > 0)
                {
                    //totalSamples = samples > 512 ? 512 : samples;

                    //ReadData(samples);
                   

                    //while (i < samples)
                    for (i =0; i<samples; i++)
                    {
                        m_SPI.WriteRead(m_sampleBuffer, 0, 2, m_recordingBuffer, i * 2, 2, 2);
                       // i++;
                    }
                    //if (m_recordingStream != null)
                        m_recordingStream.Write(m_recordingBuffer, 0, samples << 1);

                    //Debug.Print("I have: " + samples.ToString() + " samples");
                }
                //Debug.Print("no data");
            }

            samples = CommandRead(SCI_HDAT1);
            while (samples > 0)
            {
                //totalSamples = samples > 512 ? 512 : samples;

                //ReadData(samples);
                //if (m_recordingStream != null)
                for (i = 0; i < samples; i++)
                {
                    m_SPI.WriteRead(m_sampleBuffer, 0, 2, m_recordingBuffer, i * 2, 2, 2);
                    // i++;
                }
                    m_recordingStream.Write(m_recordingBuffer, 0, samples << 1);

                //Debug.Print("I have: " + samples.ToString() + " samples");

                samples = CommandRead(SCI_HDAT1);
            }

            if (m_recordingStream != null)
            {
                m_recordingStream.Close();
                m_recordingStream = null;
            }
            ..........................
               Reset();

            m_isRecording = false;
            m_oggPatch = null;
            _isReadyRecord = false;

}

One more thing I forgot: :slight_smile:
Should make this buffer bigger


static byte[] m_recordingBuffer = new byte[1024*8]; 

Also the function WritePatchFromArray(m_oggPatch) it takes long time (25 seconds on Spider and 12 seconds on Hydra) and it is on other thread. You also add a flag to make sure this function is done before you start recording.

Wouldn’t it be better to synchronize those two threads kind of like this:


static AutoResetEvent autoEvent = new AutoResetEvent(false);
private static void ThreadRecording()
{
    Debug.Print(" Waiting for WritePatchFromArray to finish ");
    autoEvent.WaitOne();
    Debug.Print("Finally it is finished, now lets start recording....");
}

//and in the WritePatchFromArray you would add this at the end of code:

  autoEvent.Set();


just a thought …

Cheers,

venc16k1q02.plg or venc16k2q00.plg will give you better quality

It works fine… Thank you so much to all of you. I wil start a long test on it and let you know.

Gianmaria

Hello, quick question. What is the performance load for recording audio (Speech medium to low quality) using a music module (Fez spider mainboard)? Will continues audio recording to a circle buffer (~30 seconds) be possible, with / without use of RLP.

Any different on a Fez domino?

Music module like http://www.ghielectronics.com/catalog/product/317

Thx

@ Dack - best to start a new thread.