Skip to content

Instantly share code, notes, and snippets.

@hcs64
Last active August 29, 2015 14:13
Show Gist options
  • Save hcs64/a99119c517701e3f66d1 to your computer and use it in GitHub Desktop.
Save hcs64/a99119c517701e3f66d1 to your computer and use it in GitHub Desktop.
make xmash 0.8 output wave files usable with (modified) ffmpeg
diff -r -u xmash08/xma_rebuild.c xmash08-mod/xma_rebuild.c
--- xmash08/xma_rebuild.c 2011-03-11 09:37:38.000000000 -0500
+++ xmash08-mod/xma_rebuild.c 2015-01-22 03:06:44.643157479 -0500
@@ -36,6 +36,44 @@
static long parse_frames(struct bitstream_reader *ibs, unsigned int frame_count, bool known_frame_count, unsigned int * total_bits_p, unsigned int max_bits, bool stereo, bool strict, bool verbose);
static int packetize(struct bitstream_reader *ibs, struct bitstream_writer *obs, struct xma_build_context * ctx, unsigned int frame_count, bool strict, bool last);
+uint8_t *make_wav_header(uint32_t srate, uint32_t size, int channels)
+{
+ uint8_t *h = malloc(wav_header_size);
+ CHECK_ERRNO(!h, "malloc");
+
+ // RIFF header
+ memcpy(&h[0x00], "RIFF", 4);
+ write_32_le(size+0x3c-8, &h[0x04]); // RIFF size
+ memcpy(&h[0x08], "WAVE", 4);
+
+ // fmt chunk
+ memcpy(&h[0x0C], "fmt ", 4);
+ write_32_le(0x10+2+18, &h[0x10]); // fmt chunk size
+
+ write_16_le(0x162, &h[0x14]); // WMA Pro
+ write_16_le(channels, &h[0x16]); // channels
+ write_32_le(srate, &h[0x18]); // sample rate **
+ write_32_le(0, &h[0x1c]); // byte rate
+ write_16_le(0x800, &h[0x20]); // block size
+ write_16_le(0, &h[0x22]); // bits per sample **
+
+ write_16_le(18, &h[0x24]); // extra data
+ write_16_le(16, &h[0x26]); // bits per sample
+ write_32_le(2, &h[0x26+2]); // channel mask
+ int decode_flags = 0;
+ decode_flags |= 0x80; // dynamic range compression
+ decode_flags |= 0x40; // len_prefix
+ decode_flags |= 2<<3; // log2_max_num_subframes
+ decode_flags |= 6; // frame len adjust
+ write_16_le(decode_flags, &h[0x26+14]); // decode_flags
+
+ // data chunk
+ memcpy(&h[0x38], "data", 4);
+ write_32_le(size, &h[0x3c]); // data chunk size
+
+ return h;
+}
+
uint8_t *make_xma_header(uint32_t srate, uint32_t size, int channels)
{
uint8_t *h = malloc(xma_header_size);
diff -r -u xmash08/xma_rebuild.h xmash08-mod/xma_rebuild.h
--- xmash08/xma_rebuild.h 2011-02-09 06:46:29.000000000 -0500
+++ xmash08-mod/xma_rebuild.h 2015-01-22 02:25:10.830356720 -0500
@@ -4,6 +4,7 @@
#include <stdint.h>
enum {
+ wav_header_size = 0x40,
xma_header_size = 0x3c,
packet_size_bytes = 0x800,
packet_header_size_bytes = 4,
@@ -15,6 +16,7 @@
default_block_size = 0x8000
};
+uint8_t *make_wav_header(uint32_t srate, uint32_t size, int channels);
uint8_t *make_xma_header(uint32_t srate, uint32_t size, int channels);
// return 0 on success, 1 if a parse error was encountered
diff -r -u xmash08/xmash.c xmash08-mod/xmash.c
--- xmash08/xmash.c 2011-10-29 22:33:54.000000000 -0400
+++ xmash08-mod/xmash.c 2015-01-22 02:25:33.840336762 -0500
@@ -177,7 +177,7 @@
}
CHECK_ERRNO(!outfile, "fopen output");
CHECK_ERRNO(
- -1 == fseek(outfile, xma_header_size, SEEK_SET), "fseek past header");
+ -1 == fseek(outfile, wav_header_size, SEEK_SET), "fseek past header");
data_offset = packet_size_bytes*str;
data_size = size-data_offset;
@@ -223,10 +223,10 @@
// write header
long finish_offset = ftell(outfile);
- uint8_t *xma_head = make_xma_header(srate, finish_offset-xma_header_size, channels);
+ uint8_t *xma_head = make_wav_header(srate, finish_offset-wav_header_size, channels);
CHECK_ERRNO(
-1 == fseek(outfile, 0, SEEK_SET), "fseek to header");
- CHECK_ERRNO( 1 != fwrite(xma_head, xma_header_size, 1, outfile) , "fwrite header");
+ CHECK_ERRNO( 1 != fwrite(xma_head, wav_header_size, 1, outfile) , "fwrite header");
CHECK_ERRNO(EOF == fclose(outfile), "fclose");
free(xma_head);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment