HydrogenAudio

Lossy Audio Compression => Other Lossy Codecs => Topic started by: Liandril on 2010-08-27 19:40:31

Title: WMA: Stream Properties Object (WAVEFORMATEX)
Post by: Liandril on 2010-08-27 19:40:31
Hi everyone and first of all: sorry for my English!

I'm currently writing an extraction tool for a german game that uses .xwb-files (Microsoft XACT Wavebanks). There
are already quite a lot of xwb extraction tools, but most of them only work for older games, because Microsoft
changes the file format from time to time. So "old" extraction tools won't work with "new" xwbs.

xwb files can contain a collection of waves (pcm, adpcm, wma or xma). Unfortunately, there is currently no tool
that's able to extract wma data from "newer" xwb files... therefor I'm writing my tool, trying to extract the .xwb to valid .wma files.
Extracting the wma DATA is quite easy and I'm able to transform them to a ASF DATA OBJECT (probably you know: wma is actually ASF
(roughly spoken). And a valid .wma file consists of at least 5 objects:Header Object,  File Properties Object, Stream Properties
Object, Header Extension Object and Data Object).
My problem is the Stream Properties Object which contains a WAVEFORMATEX (http://msdn.microsoft.com/en-us/library/ms720517%28VS.85%29.aspx) structure. Appended to the WAVEFORMATEX
structure is a "Code Specific Data Section" for WMA (which is not described in the ASF Specification (http://www.microsoft.com/windows/windowsmedia/forpros/format/asfspec.aspx%5dASF/WMA-Specification)):

dwSamplesPerBlock   DWORD
wEncodeOptions      WORD
dwSuperBlockAlign   DWORD

Unfortunately I've no idea how to determine the values for these fields (especially the wEncodeOptions). 
So I'd really, really appreciate, if someone could give me a hint about this WMA-Code specific data section...
Thanks a lot!
Title: WMA: Stream Properties Object (WAVEFORMATEX)
Post by: saratoga on 2010-08-27 20:28:36
Most of the fields in the Stream Properties Object will come from whatever container you're taking the stream from.  From the rockbox ASF parser:

Code: [Select]
                        read_uint16le(fd, &wfx->codec_id);
                        read_uint16le(fd, &wfx->channels);
                        read_uint32le(fd, &wfx->rate);
                        read_uint32le(fd, &wfx->bitrate);
                        wfx->bitrate *= 8;
                        read_uint16le(fd, &wfx->blockalign);
                        read_uint16le(fd, &wfx->bitspersample);
                        read_uint16le(fd, &wfx->datalen);

....

                       } else if (wfx->codec_id == ASF_CODEC_ID_WMAV2) {
                            read(fd, wfx->data, 6);
                            lseek(fd,current.size - 24 - 72 - 6,SEEK_CUR);
                            wfx->audiostream = flags&0x7f;
                        }

...

     extradata = wfx->data;
    if (s->version == 1 && wfx->datalen >= 4) {
        flags2 = extradata[2] | (extradata[3] << 8);
    }else if (s->version == 2 && wfx->datalen >= 6){
        flags2 = extradata[4] | (extradata[5] << 8);
    }
    s->use_exp_vlc = flags2 & 0x0001;
    s->use_bit_reservoir = flags2 & 0x0002;
    s->use_variable_block_len = flags2 & 0x0004;


So basically the fields in that struct are things like sample rate, transform size and any misc features the codec needs enabled (like variable length coding for exponents).  The asf view tool gives you some hints (sample rate, etc) but won't tell you about block lengths and such (I think it lumps those into the "extra data" field of the stream properties object).
Title: WMA: Stream Properties Object (WAVEFORMATEX)
Post by: Liandril on 2010-08-27 21:46:20
Most of the fields in the Stream Properties Object will come from whatever container you're taking the stream from.  From the rockbox ASF parser:

Code: [Select]
            
....
                       } else if (wfx->codec_id == ASF_CODEC_ID_WMAV2) {
                            read(fd, wfx->data, 6);
                            lseek(fd,current.size - 24 - 72 - 6,SEEK_CUR);
                            wfx->audiostream = flags&0x7f;
                        }
...
     extradata = wfx->data;
    if (s->version == 1 && wfx->datalen >= 4) {
        flags2 = extradata[2] | (extradata[3] << 8);
    }else if (s->version == 2 && wfx->datalen >= 6){
        flags2 = extradata[4] | (extradata[5] << 8);
    }
    s->use_exp_vlc = flags2 & 0x0001;
    s->use_bit_reservoir = flags2 & 0x0002;
    s->use_variable_block_len = flags2 & 0x0004;


So basically the fields in that struct are things like sample rate, transform size and any misc features the codec needs enabled (like variable length coding for exponents).  The asf view tool gives you some hints (sample rate, etc) but won't tell you about block lengths and such (I think it lumps those into the "extra data" field of the stream properties object).

Wow, thanks a lot for the quick response  ... I posted my request in other audio forums/file format forums quite a while ago... and didn't receive ANY answer so far.. so: THANKS! From the infos within the .xwb file, I can get/calculate the values "within" the WAVEFORMATEX structure (channels, bitrate, block align/length, bitspersample)... my problem are just the extradata / codec specific data... so thanks for this code. I'll try to figure out, what it means
Title: WMA: Stream Properties Object (WAVEFORMATEX)
Post by: saratoga on 2010-08-27 22:04:47
If it helps virtually all WMA files in existence define use_exp_vlc = use_bit_reservoir  = use_variable_block_len = 1.  Knowing that, the sample rate, bits per sample, etc you might be able to track down the resulting bytes in the source bitstream.