Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.

My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

typedef struct
{
	uint32_t id;
	uint32_t size;
} Chunk;

typedef struct
{
	Chunk super;
	uint32_t type;
} RIFF;

typedef struct
{
	uint16_t compressionCode;
	uint16_t numChannels;
	uint32_t sampleRate;
	uint32_t avgBytesPerSecond;
	uint16_t blockAlign;
	uint16_t bitsPerSample;
	uint16_t extraFormatBytes;
} FMT;

void displaySample(int16_t sample, int columns)
{
	int32_t value = (columns * (sample - INT16_MIN)) / (INT16_MAX - INT16_MIN);
	char buffer[columns + 1];
	memset(buffer, ' ', columns);
	buffer[columns] = '\0';
	buffer[value] = '@';
	printf("%s\n", buffer);
}

int main(int argc, char* argv[])
{
	FILE* f = fopen(argv[1], "rb");
	FILE* o = fopen(argv[2], "wb");

	RIFF riff;
	fread(&riff, 1, sizeof(riff), f);
	if(riff.super.id != 0x46464952 || riff.type != 0x45564157)
	{
		printf("Bad WAV magic! %x %x\n", riff.super.id, riff.type);
		fclose(f);
		return 1;
	}

	off_t cur = 4;

	int columns;
	if(argc > 3)
		columns = atoi(argv[3]);

	Chunk chunk;

	FMT fmt;

	while(cur < riff.super.size)
	{
		fread(&chunk, 1, sizeof(chunk), f);
		cur += sizeof(chunk);

		printf("Chunk: %x\n", chunk.id);

		uint8_t* data = (uint8_t*) malloc(chunk.size);
		fread(data, 1, chunk.size, f);
		cur += chunk.size;

		if(chunk.id == 0x20746D66)
		{
			memcpy(&fmt, data, sizeof(fmt));
			printf("Compression code: %d\n", fmt.compressionCode);
			printf("Channels: %d\n", fmt.numChannels);
			printf("Sample rate: %d\n", fmt.sampleRate);
			printf("Average bytes per second: %d\n", fmt.avgBytesPerSecond);
			printf("Block align: %d\n", fmt.blockAlign);
			printf("Bits per sample: %d\n", fmt.bitsPerSample);
			printf("Extra format bytes: %d\n", fmt.extraFormatBytes);
		} else if(chunk.id == 0x61746164)
		{
			if(fmt.bitsPerSample == 16 && fmt.numChannels == 2)
			{
				if(argc > 3)
				{
					int i;
					for(i = 0; i < (chunk.size / fmt.blockAlign); ++i)
					{
						int16_t sample = *((int16_t*)(data + (i * 4)));
						displaySample(sample, columns);
					}
				}
			}
			fwrite(data, 1, chunk.size, o);
		}

		free(data);
	}
	fclose(o);
	fclose(f);
}