lut_gen.cpp 3.89 KB
Newer Older
Erik Faye-Lund's avatar
Erik Faye-Lund committed
1
2
3
4
5
6
7
/*
	this is the lut-generator for pimpmobile.
	
	the delta-luts are dependant on the sample-rate, and must be re-generated
	whenever the sample-rate-config has changed.
*/

Erik Faye-Lund's avatar
Erik Faye-Lund committed
8
9
10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
11
#include <stddef.h>
Erik Faye-Lund's avatar
Erik Faye-Lund committed
12
#include <math.h>
13
#include <typeinfo>
Erik Faye-Lund's avatar
Erik Faye-Lund committed
14

Erik Faye-Lund's avatar
Erik Faye-Lund committed
15
16
#include "src/pimp_config.h" // get the current config
#include "src/pimp_math.h"
17

Erik Faye-Lund's avatar
Erik Faye-Lund committed
18
void error(const char *reason)
Erik Faye-Lund's avatar
Erik Faye-Lund committed
19
{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
20
21
22
	fprintf(stderr, "error %s\n", reason);
	exit(1);
}
Erik Faye-Lund's avatar
Erik Faye-Lund committed
23
24

unsigned short linear_freq_lut[12 * 64];
Erik Faye-Lund's avatar
Erik Faye-Lund committed
25
unsigned short amiga_freq_lut[(AMIGA_DELTA_LUT_SIZE / 2) + 1];
Erik Faye-Lund's avatar
Erik Faye-Lund committed
26
27
28

float get_normal_noise()
{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
29
	float r = 0.0f;
Erik Faye-Lund's avatar
Erik Faye-Lund committed
30
31
32
33
34
35
36
37
38
	for (unsigned j = 0; j < 12; ++j)
	{
		r += rand();
	}
	r /= RAND_MAX;
	r -= 6;
	return r;
}

39
template <typename T>
Erik Faye-Lund's avatar
Erik Faye-Lund committed
40
void print_lut(FILE *fp, T *lut, size_t size)
41
{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
42
	int line_start = ftell(fp);
43
44
	for (size_t i = 0; i < size; ++i)
	{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
45
46
47
48
49
50
51
52
		fprintf(fp, "%d, ", lut[i]);
		
		// some newlines every now and then isn't too annoying ;)
		if (ftell(fp) > (line_start + 80))
		{
			fprintf(fp, "\n\t", line_start, ftell(fp));
			line_start = ftell(fp);
		}
53
54
55
56
	}
}

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
Erik Faye-Lund's avatar
Erik Faye-Lund committed
57
#define PRINT_LUT(fp, x) print_lut(fp, x, ARRAY_SIZE(x))
58

Erik Faye-Lund's avatar
Erik Faye-Lund committed
59
60
int main(int argc, char *argv[])
{
61

Erik Faye-Lund's avatar
Erik Faye-Lund committed
62
63
#if 0
	/* generate */
64
65
66
67
68
69
	for (unsigned o = 0; o < 1; ++o)
	{
		for (unsigned n = 0; n < 2; ++n)
		{
			for (int fine_tune = -8; fine_tune < 8; ++fine_tune)
			{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
70
				printf("%d, ", __pimp_get_amiga_period(n + o * 12, fine_tune) / 4);
71
72
73
74
75
			}
		}
		printf("\n");
	}
	return 0;
Erik Faye-Lund's avatar
Erik Faye-Lund committed
76
#endif
77

Erik Faye-Lund's avatar
Erik Faye-Lund committed
78
	/* TODO: use some flags and stuff to decide what to dump and to what filename */
Erik Faye-Lund's avatar
Erik Faye-Lund committed
79
	if (1)
Erik Faye-Lund's avatar
Erik Faye-Lund committed
80
	{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
81
82
83
84
85
86
87
88
89
90
91
92
93
		// generate a lut for linear frequencies
		for (unsigned i = 0; i < 12 * 64; ++i)
		{
			linear_freq_lut[i] = unsigned(float(pow(2.0, i / 768.0) * 8363.0 / (1 << 8)) * float(1 << 9) + 0.5);
		}
		
		// now dump it
		FILE *fp = fopen("src/linear_delta_lut.h", "wb");
		if (!fp) error("failed to open out-file");
		fprintf(fp, "const u16 linear_delta_lut[%d] =\n{\n\t", ARRAY_SIZE(linear_freq_lut));
		PRINT_LUT(fp, linear_freq_lut);
		fprintf(fp, "\n};\n\n");
		fclose(fp);
Erik Faye-Lund's avatar
Erik Faye-Lund committed
94
95
	}

Erik Faye-Lund's avatar
Erik Faye-Lund committed
96
	if (1)
Erik Faye-Lund's avatar
Erik Faye-Lund committed
97
	{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
		// generate a lut for amiga frequencies
		for (unsigned i = 0; i < (AMIGA_DELTA_LUT_SIZE / 2) + 1; ++i)
		{
			unsigned p = i + (AMIGA_DELTA_LUT_SIZE / 2);
			amiga_freq_lut[i] = (unsigned short)(((8363 * 1712) / float((p * 32768) / AMIGA_DELTA_LUT_SIZE)) * (1 << 6) + 0.5);
		}
		
		// now dump it
		FILE *fp = fopen("src/amiga_delta_lut.h", "wb");
		if (!fp) error("failed to open out-file");
		fprintf(fp, "const u16 amiga_delta_lut[%d] =\n{\n\t", ARRAY_SIZE(amiga_freq_lut));
		PRINT_LUT(fp, amiga_freq_lut);
		fprintf(fp, "\n};\n\n");
		fclose(fp);
Erik Faye-Lund's avatar
Erik Faye-Lund committed
112
	}
113
114

#if 0
Erik Faye-Lund's avatar
Erik Faye-Lund committed
115
	// testcode for amiga frequency-lut
Erik Faye-Lund's avatar
Erik Faye-Lund committed
116
117
118
	for (unsigned period = 1; period < 32767; period += 17)
	{
		float frequency1 = (8363 * 1712) / float(period);
119
		float delta1 = frequency1 / SAMPLERATE;
Erik Faye-Lund's avatar
Erik Faye-Lund committed
120
121
122
123
124
125
126
127
128
		delta1 = unsigned(delta1 * (1 << 12) + 0.5) * (1.0 / (1 << 12));
		
		float delta2 = get_amiga_delta(period) * (1.0 / (1 << 12));
		
//		printf("%f %f\n", delta1, delta2);
		printf("%f %f, %f\n", delta1, delta2, fabs(delta1 - delta2) / delta1);
	}
#endif

Erik Faye-Lund's avatar
Erik Faye-Lund committed
129
#if 0 // testcode for linear frequency-lut
Erik Faye-Lund's avatar
Erik Faye-Lund committed
130
131
132
133
134
	for (unsigned i = 0; i < 12 * 14; ++i)
	{
//		Period = 10*12*16*4 - Note*16*4 - FineTune/2;
//		Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4));
		
Erik Faye-Lund's avatar
Erik Faye-Lund committed
135
		for (int fine_tune = -64; fine_tune < 64; fine_tune += 16)
Erik Faye-Lund's avatar
Erik Faye-Lund committed
136
		{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
137
			int period = (10 * 12 * 16 * 4) - i * (16 * 4) - fine_tune / 2;
Erik Faye-Lund's avatar
Erik Faye-Lund committed
138
139
			
			float frequency1 = 8363 * pow(2.0, float(6 * 12 * 16 * 4 - period) / (12 * 16 * 4));
140
			float delta1 = frequency1 / SAMPLERATE;
Erik Faye-Lund's avatar
Erik Faye-Lund committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
			delta1 = unsigned(delta1 * (1 << 12) + 0.5) * (1.0 / (1 << 12));
			
			float delta2 = get_linear_delta(period) * (1.0 / (1 << 12));
			
			printf("%f ", (delta1 - delta2) / delta1);
//			printf("%f\n", delta1);
		}
		printf("\n");
	}
#endif

#if 0
	for (unsigned i = 0; i < 304; ++i)
	{
		float r;
		
		do {
			r = get_normal_noise() * (2.0 / 3) * (1 << 6);
		}
		while (r > 127 || r < -128);
		
		printf("%i, ", int(r));
	}
#endif
}