#include <limits.h>
#include "instruments.h"
#include "noise.h"

/* Note definition helpers */
#define W(v) {v, 1}
#define H(v) {v, 0.5}
#define Q(v) {v, 0.25}
#define E(v) {v, 0.125}
#define S(v) {v, 0.0625}
/* Dotted */
#define DW(v) {v, 1 * 1.5}
#define DH(v) {v, 0.5 * 1.5}
#define DQ(v) {v, 0.25 * 1.5}
#define DE(v) {v, 0.125 * 1.5}
#define DS(v) {v, 0.0625 * 1.5}
/* Triplets */
#define TW(v) {v, 1 / 3.0}
#define TH(v) {v, 0.5 / 3.0}
#define TQ(v) {v, 0.25 / 3.0}
#define TE(v) {v, 0.125 / 3.0}
#define TS(v) {v, 0.0625 / 3.0}
/* Rest */
#define R INT_MIN

/* Helper for making channels */
#define SONG_BEGIN struct channel_t channels[] = {
#define SONG_END };\
int num_channels = sizeof(channels) / sizeof(struct channel_t);
#define CHANNEL(idx, repeat, vol, pan, instrument, tempo, beat_note, transpose)\
{notes_##idx, sizeof(notes_##idx) / sizeof(struct note_t), 0, 0, (repeat),\
(vol), (pan), &(instrument), (tempo), (beat_note), (transpose)},

#if 1
/* Single test note */
static struct note_t notes_main[] = {W(0)};
SONG_BEGIN
CHANNEL(main, -1, 1, 0.5, sine, 30, 1, 0)
SONG_END
#elif 0
/* Final Fantasy theme */
struct note_t notes_main[] = {E(-12), E(-10), E(-8), E(-5), E(0), E(2), E(4),
E(7), E(12), E(7), E(4), E(0), E(-5), E(-8), E(-10), E(-12), E(-15), E(-13),
E(-12), E(-8), E(-3), E(-1), E(0), E(4), E(9), E(4), E(0), E(-3), E(-8),
E(-12), E(-13), E(-15)};
SONG_BEGIN
CHANNEL(main, -1, 1, 0.5, sine, 92, 0.25, 0)
SONG_END
#elif 0
/* In the Hall of the Mountain King */
struct note_t notes_main[] = {E(-17), E(-15), E(-14), E(-12), E(-10), E(-14),
Q(-10), E(-11), E(-15), Q(-11), E(-12), E(-16), Q(-12), E(-17), E(-15), E(-14),
E(-12), E(-10), E(-14), E(-10), E(-5), E(-7), E(-10), E(-14), E(-12), Q(-10),
E(-17)};
SONG_BEGIN
CHANNEL(main, 0, 1, 0.5, sawtooth, 92, 0.25, 0)
SONG_END
#elif 0
/* Rez, out of time, tune, and everything else */
struct note_t notes_main[] = {E(-12), E(0), E(-12), E(8), E(-12), E(4), E(-10),
E(4), E(-12), E(4), E(-10), E(8), E(-12), E(0), E(-12), E(8), E(-12), E(4),
E(-10), E(4), E(-12), E(4), E(8), E(-12), E(0), E(-12), E(8), E(-12), E(4),
E(-12), E(-10), E(-12), E(4), E(-10), E(4), E(8), E(-12), E(0), E(-12), E(8),
E(-12), E(4), E(-10), E(0), E(-12), E(4), E(8), E(-12), E(0), E(-12), E(2),
E(-12), E(17), E(-12), E(8), E(-12), E(0), E(-12), E(2), E(-12), E(2), E(-12),
E(8), E(-12), E(2), E(-12), E(2), E(-12), E(8), E(-12), E(2), E(-12), E(2),
E(-12), E(2), E(-12), E(8), E(-12), E(2), E(-12), E(2), E(-12), E(17), E(-12),
E(0), E(-12), E(8), E(-12), E(4), E(-12), E(4), E(-10), E(4), E(8)};
SONG_BEGIN
CHANNEL(main, 0, 1, 0.5, tri, 200, 0.25, 12)
SONG_END
#elif 0
/* Call of Ktulu */
struct note_t notes_main[] = {
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7),
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7),
E(-7), E(13), E(5), E(8), E(1), E(8), E(13), E(8),
E(-7), E(13), E(5), E(8), E(1), E(8), E(13), E(8),
E(-7), E(15), E(7), E(10), E(3), E(10), E(15), E(10),
E(-7), E(15), E(7), E(10), E(3), E(10), E(15), E(10),
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7),
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7),
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7),
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7),
E(-7), E(13), E(5), E(8), E(1), E(8), E(13), E(8),
E(-7), E(13), E(5), E(8), E(1), E(8), E(13), E(8),
E(-7), E(15), E(7), E(10), E(3), E(10), E(15), E(10),
E(-7), E(15), E(7), E(10), E(3), E(10), E(15), E(10),
E(-7), E(12), E(5), E(8), E(0), E(4), E(12), E(7), Q(8),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-12), E(0), E(3), E(2), E(7), E(2), E(3), E(-5),
E(-6), E(0), E(3), E(2), E(7), E(2), E(3), E(0),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12),
E(-7), E(0), E(5), E(8), E(-7), E(1), E(5), E(8), E(-7), E(2), E(5), E(8),
E(-7), E(3), E(5), E(12)
};
SONG_BEGIN
CHANNEL(main, 0, 1, 0.5, sawtooth, 92, 0.25, 0)
SONG_END
#elif 0
/* Hyrule Theme */
struct note_t notes_top[] = {
/* Intro */
H(1), TQ(R), TQ(R), TQ(1), TQ(1), TQ(1), TQ(1),
TQ(1), TQ(R), TQ(-1), Q(1), TQ(R), TQ(R), TQ(1), TQ(1), TQ(1), TQ(1),
TQ(1), TQ(R), TQ(-1), Q(1), TQ(R), TQ(R), TQ(1), TQ(1), TQ(1), TQ(1),
S(1), S(R), S(-4), S(-4), S(-4), S(R), S(-4), S(-4), S(-4), S(R), S(-4), S(-4),
		E(-4), E(-4),
/* Part 1 */
E(1), E(R), {-4, 0.25 + 0.125}, S(R), S(1), S(1), S(3), S(5), S(6),
H(8), E(R), E(8), TQ(8), TQ(9), TQ(11),
H(13), TQ(R), TQ(13), TQ(13), TQ(13), TQ(11), TQ(9),
TQ(11), TQ(R), TQ(9), H(8), Q(8),
E(6), S(6), S(8), H(9), E(8), E(6),
E(4), S(4), S(6), H(8), E(6), E(4),
E(3), S(3), S(5), H(7), Q(10),
S(8), S(R), S(-4), S(-4), S(-4), S(R), S(-4), S(-4), S(-4), S(R), S(-4), S(-4),
		E(-4), E(-4),
/* Part 2 */
E(1), E(R), {-4, 0.25 + 0.125}, S(R), S(1), S(1), S(3), S(5), S(6),
H(8), E(8), TQ(8), TQ(9), TQ(11),
DH(13), Q(16),
E(15), E(R), H(12), Q(8),
DH(9), Q(13),
E(12), E(R), H(8), Q(8),
DH(9), Q(13),
E(12), E(R), H(8), Q(5),
DH(6), Q(9),
Q(8), H(4), Q(1),
E(3), S(3), S(5), H(7), Q(10),
S(8), S(R), S(-4), S(-4), S(-4), S(R), S(-4), S(-4), S(-4), S(R), S(-4), S(-4),
		E(-4), E(-4)
/* TODO: repeat */
};
struct note_t notes_middle[] = {
/* Intro */
H(-7), TQ(R), TQ(R), TQ(-7), TQ(-7), TQ(-7), TQ(-7),
TQ(-9), TQ(R), TQ(-9), Q(-9), Q(R), TQ(-9), TQ(-9), TQ(-9),
TQ(-8), TQ(R), TQ(-8), Q(-8), TQ(R), TQ(R), TQ(-8), TQ(-8), TQ(-8), TQ(-8),
S(-8), S(R), S(-12), S(-12), S(-12), S(R), S(-12), S(-12), S(-12), S(R), S(-12),
		S(-12), E(-12), E(-12),
/* Part 1 */
Q(-7), TQ(-7), TQ(-7), TQ(-9), E(-7), S(R), S(-7), S(-7), S(-6), S(-4), S(-2),
E(-1), S(R), S(1), S(1), S(3), S(5), S(6), Q(8), TQ(-1), TQ(1), TQ(3),
E(4), S(R), S(-3), S(-3), S(-1), S(1), S(3), TQ(5), TQ(R), TQ(5), TQ(5), TQ(3),
		TQ(1),
TQ(5), TQ(R), TQ(-1), TQ(-1), TQ(-1), TQ(-3), TQ(-1), TQ(R), TQ(-1), TQ(-1),
		TQ(-3), TQ(-1),
E(-3), S(-3), S(-4), E(-3), S(-3), S(-1), Q(1), E(-1), E(-3),
E(-4), S(-4), S(-6), E(-4), S(-4), S(-3), Q(-1), E(-3), E(-4),
Q(-5), E(-5), S(-5), S(-4), E(-2), S(-2), S(0), E(1), E(3),
E(0), S(-12), S(-12), E(-12), S(-12), S(-12), E(-12), S(-12), S(-12), E(-12),
		E(-12),
/* Part 2 */

};
SONG_BEGIN
CHANNEL(top, 0, 1, 0.5, sawtooth, 150, 0.25, 0)
CHANNEL(middle, 0, 1, 0.5, square, 150, 0.25, 0)
SONG_END
#elif 1
/* Zelda Dungeon Theme */
struct note_t notes_bass[] = {
Q(-14), Q(R),
Q(-11), Q(-7),
Q(-8), Q(-15),
H(R),
Q(-16), Q(R),
E(-16), S(R), S(-13), E(R), E(-8),
Q(-9), Q(-16),
H(R),
S(-17), S(-18), Q(-17), E(R),
E(-14), S(R), S(-6), E(R), E(-7), 
S(-18), S(-19), Q(-18), E(R),
E(-14), S(R), S(-7), E(R), E(-8),
S(-18), S(-15), S(-12), S(-15), S(-12), S(-9), S(-12), S(-9),
S(-6), S(-10), S(-6), S(-3), S(0), S(-3), S(-6), S(-10), S(-6), S(-10), S(-12),
		S(-15)
};
struct note_t notes_treble[] = {
S(-2), S(1), S(5), S(6), S(-2), S(1), S(5), S(6),
S(-2), S(1), S(5), S(6), S(-2), S(1), S(5), S(6),
S(-3), S(0), S(5), S(6), S(-3), S(0), S(5), S(6),
S(-3), S(0), S(5), S(6), S(-3), S(0), S(5), S(6),
S(-4), S(-1), S(5), S(6), S(-4), S(-1), S(5), S(6),
S(-4), S(-1), S(5), S(6), S(-4), S(-1), S(5), S(6),
S(-5), S(-2), S(5), S(6), S(-5), S(-2), S(5), S(6),
S(-5), S(-2), S(5), S(7), S(-5), S(-2), S(5), S(7),
S(-6), S(-2), S(3), S(5), S(-6), S(-2), S(3), S(5),
S(-6), S(-2), S(3), S(5), S(-6), S(-2), S(3), S(5),
S(-7), S(-2), S(3), S(5), S(-7), S(-2), S(3), S(5),
S(-7), S(-2), S(3), S(5), S(-7), S(-2), S(3), S(5),
S(-9), S(-3), S(0), S(3), S(-3), S(0), S(3), S(6),
S(0), S(3), S(6), S(3), S(6), S(9), S(6), S(9), S(12), S(9), S(12), S(15)
};
SONG_BEGIN
CHANNEL(treble, 0, 1, 0.5, sawtooth, 75, 0.25, 0)
CHANNEL(bass, 0, 1, 0.5, square, 75, 0.25, 0)
SONG_END
#endif

