0
0

Ok, I’ve been to ID3.org, and I plan to become intimately familiar with the docs there, but a quick and dirty explanation (if possible) from one of you who knows would sure be appreciated in the mean time.

I’m using FSOUND_Stream_GetTagField in C#. Since C# doesn’t support void pointers, I’m using a string ref in the “val” field. This works great for ID3V1 fields, but val always comes back empty with ID3V2 fields. What’s the difference??

Thanks…
Lance

  • You must to post comments
0
0

Ok…. after finding another post by someone with the same problem, and after looking at the fmod sample project, and after some research on how to manipulate IntPtr in C#, I found my answer (and judging from some of the posts I’ve seen, it’s the answer for a few other people also). ID3V2 pads the beginning of certain value fields with a text encoding byte. For ISO-8859-1, this byte is a hex 00. Fmod sets val to this byte address as the beginning of the value field. Of course, a hex 00 is a string termination character, so if you’re assigning a string the value at the address returned by val, you’ll get (for ID3V2 tags) a null string. Here’s the code I used to get my ID3V2 data (I’m only getting three fields here, but you can just add case statements for the rest):

    private void getinfo(ref Song song)
    {   
        IntPtr val = new IntPtr(0);
        string tmp;
        string name = "";
        int length = 0;
        int numFields = 0;
        IntPtr stream = new IntPtr(0);
        stream = FmodManaged.FSOUND.Function.Stream.FSOUND_Stream_Open(song.Path,
            40, 0 , 0); 
        FmodManaged.FSOUND.Enums.FSOUND_TAGFIELD_TYPE Ftype = 
            new FmodManaged.FSOUND.Enums.FSOUND_TAGFIELD_TYPE();

        //Get the number of tag fields
        if(FmodManaged.FSOUND.Function.Stream.FSOUND_Stream_GetNumTagFields
            (stream,ref numFields) != false)
        {
            for(int count = 0; count < numFields; ++count)
            {
                //Get the info for each tag field
                FmodManaged.FSOUND.Function.Stream.FSOUND_Stream_GetTagField(stream,
                    count,ref Ftype,ref name,ref val,ref length);

                //Increment IntPtr location for ID3V2
                if(Ftype == FmodManaged.FSOUND.Enums.FSOUND_TAGFIELD_TYPE.FSOUND_TAGFIELD_ID3V2
                    && name[0] == 'T')
                    val = new IntPtr(val.ToInt32() + 1);

                tmp = Marshal.PtrToStringAnsi(val);
                switch(name)
                {
                    case "ARTIST":
                        song.Artist = tmp;
                        break;
                    case "ALBUM":
                        song.Album = tmp;
                        break;
                    case "TITLE":
                        song.Title = tmp;
                        break;
                    case "TPE1":
                        if(song.Artist == null)
                            song.Artist = tmp;
                        break;
                    case "TALB":
                        if(song.Album == null)
                            song.Album = tmp;
                        break;
                    case "TIT2":
                        if(song.Title == null)
                            song.Title = tmp;
                        break;
                }
            }
        }
    }

“Song” is just a struct I defined elsewhere in the program.

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.