Exception when readin MP3 from microSD

Hi

I’m trying to read MP3 file from microSD card and to announce it by using the MP3 extension for FEX Domino.
Sometime it works but sometimes I get the following exception when reading the file:

Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (1)

#### Microsoft.SPOT.IO.NativeFileStream::Read [IP: 0000] ####
#### System.IO.FileStream::Read [IP: 0028] ####

A first chance exception of type ‘System.ObjectDisposedException’ occurred in Microsoft.SPOT.IO.dll
#### Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (7) ####
#### Microsoft.SPOT.IO.NativeFileStream::GetLength [IP: 0000] ####
#### System.IO.FileStream::get_Length [IP: 001b] ####
Uncaught exception
Message: Exception was thrown: System.ObjectDisposedException
#### Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (9) ####
#### Microsoft.SPOT.IO.NativeFileStream::GetLength [IP: 0000] ####
#### System.IO.FileStream::get_Length [IP: 001b] ####
Uncaught exception
Stack Trace: Microsoft.SPOT.IO.NativeFileStream::Read
System.IO.FileStream::Read

Here is the basic code:


using System;
using System.Text;
using System.Threading;
using System.IO;
using System.IO.Ports;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.IO;

public static void Main()
{
      FileStream file= null;
      byte[] mp3data = new byte[2048];
      string mp3SampleFile;

      // microSD Card is inserted
      // Create a new storage device
      PersistentStorage sdPS = new PersistentStorage("SD");
      // Mount the file system
      sdPS.MountFileSystem();
            
      if (VolumeInfo.GetVolumes()[0].IsFormatted)
      {
           string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
           string[] files = Directory.GetFiles(rootDirectory);
           string[] folders = Directory.GetDirectories(rootDirectory);
                
            mp3SampleFile = Directory.GetFiles(folders[0]);
               
       }
       else
       {
               Debug.Print("Storage is not formatted. Format on PC with FAT32/FAT16 first.");
       }

       EZ_Extensions.MP3.Initialize();
       // The loudest volume
       FEZ_Extensions.MP3.SetVolume(255, 255);  
            
       try
       {
              file = File.Open(mp3SampleFile , FileMode.Open, FileAccess.Read);

              int size;

              do
              {
                    size = file.Read(mp3data, 0, 2048);
                    FEZ_Extensions.MP3.SendData(mp3data);

              } while (size > 0);
        }
        catch (Exception ex)
        {
               Debug.Print("Message: " + ex.Message);
               Debug.Print("Stack Trace: " + ex.StackTrace);
               Debug.GC(true);
         }
         finally
         {
                if (file != null)
                    file.Close();
         }
            
            return 0;
     }
}        

Your program is ending…

No return 0 at end.

Use Thread.sleep(Timeout.Infinite)

You’r right, my mistake, I mismatched code of two functions.
I have Thread.sleep(Timeout.Infinite) at the end of my code, not return 0.
Any way, the exception is still happening.

Should mp3samplefile be an array?

The exception is still happening because the File object is getting collected by the GC.

mp3sample can be an array but I use only one file.
How to overcome the GC?

The problem is not in GC, your code is disposing an object (or dereferencing an object) and then later you are trying to use an object that is no longer available.

Can you give more explanations?
The exception happened when calling to file.Read in the loop that read the mp3 file.
Where and what object is disposed during that process?

OK, so lets look at what things the error is telling you.

Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (1)

You have had an object disposed and now you’re trying to use it.

Microsoft.SPOT.IO.NativeFileStream::Read [IP: 0000]

You’re trying to READ from a file stream that no longer exists (ie was disposed)

System.IO.FileStream::Read [IP: 0028]

A first chance exception of type ‘System.ObjectDisposedException’ occurred in Microsoft.SPOT.IO.dll

This is a first chance exception, lets see if things can continue.

Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (7)

Microsoft.SPOT.IO.NativeFileStream::GetLength [IP: 0000]

The GetLength call also failed, so it’s not going anywhere.

Here’s a question, how many times does your read-loop step around? IE do you read 2k of the file before failure? 4k?

You can do a few different things here to try to diagnose.

  1. Write a simple program that does nothing related to the MP3 decoder, just handles the file. When that works, you know that adding in the MP3 decoding bits will work.

  2. find a sample program that handles files that you can learn from the structure of their file handling.

  3. debug.print lots of places, and use F11 to step through your code, to see where things are actually going wrong.

  4. a combination of all of them!

But fundamentally, you aren’t handling the file stream properly and fixing that will let you move past that error…

Thanks for the info
I try to read mp3 file and use it like I saw this project:
(link removed)
I’ll try the step you suggeted.
Thanks

This is explained in the free ebook in full details :wink:

Try replacing do while loop with while loop. When you get a zero
size read you are passing to mp3

I still don’t understand what object is disposed.
The problem is that when I debug step by step nothing happen and the same when I close the call to FEZ_Extensions.MP3.SendData();
Just when I run it without debugging and call the function, the Exception happened.
I close the file handle just after calling to FEZ_Extensions.MP3.SendData(), so, why its disposed?

Did you try to change the loop as suggested by Mike ?

Try this :


            int start = 0;

            while ((start = file.Read(mp3data,start,2048)) > 0)
            {
                FEZ_Extensions.MP3.SendData(mp3data);
            }

I tried that suggestion.

When I try to use:

while ((start = file.Read(mp3data, start, 2048)) > 0)
{
         FEZ_Extensions.MP3.SendData(mp3data);
}

I get this exception:

Exception System.ArgumentException - 0xfd000000 (1)

#### Microsoft.SPOT.IO.NativeFileStream::Read [IP: 0000] ####
#### System.IO.FileStream::Read [IP: 0028] ####
#### GPSpeak.Speak::Play [IP: 0075] ####
#### GPSpeak.Program::Main [IP: 000c] ####

A first chance exception of type ‘System.ArgumentException’ occurred in Microsoft.SPOT.IO.dll
\SD\VOICES\1.MP3

When I try to use:

while ((start = file.Read(mp3data, 0, 2048)) > 0)
{
         FEZ_Extensions.MP3.SendData(mp3data);
}

I get this exception:

Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (1)

#### Microsoft.SPOT.IO.NativeFileStream::Read [IP: 0000] ####
#### System.IO.FileStream::Read [IP: 0028] ####
#### GPSpeak.Speak::Play [IP: 0074] ####
#### GPSpeak.Program::Main [IP: 000c] ####

A first chance exception of type ‘System.ObjectDisposedException’ occurred in Microsoft.SPOT.IO.dll
\SD\VOICES\1.MP3
#### Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (7) ####
#### Microsoft.SPOT.IO.NativeFileStream::GetLength [IP: 0000] ####
#### System.IO.FileStream::get_Length [IP: 001b] ####
Uncaught exception

When I try to close the file just after I opened it I get an exception:

Exception System.ObjectDisposedException - 0x00000000 (6)

#### System.IO.FileStream::get_Length [IP: 0009] ####

Uncaught exception

When I debug it step by step it doesn’t happen.
Please advice

Thanks
ami

Have you tried to just read the file without sending to mp3? Need to determine if the problem is related to file reading or mp3 playing.

Yes, I tried that and it works fine without exceptions.
Exceptions happened when sending the data to mp3.
for example:


while ((start = file.Read(mp3data, 0, 2048)) > 0)
{
           FEZ_Extensions.MP3.SendData(mp3data);
}

Could it be that the file contains bad data?

Maybe, but if so, why when I debug it step by step it works?

Have you tried multiple files?

When you run in the debugger timing is very different. GC would happen at a different time.