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
|
#include <stdio.h>
#include <stdint.h>
double _fabs(double a)
{
return a<0?a*-1:a;
}
typedef struct {
int pclkdiv_idx;
int bitrate;
int x;
int y;
double err;
} result_t;
static const int pclkdiv[] = { 1, 2, 4, 8 };
int main(int argc, char *argv[])
{
result_t best;
best.err = 999999;
if(argc < 3) {
printf("Usage: %s samplerate bitwidth channelcount\n", argv[0]);
printf("Example: 48KHz 16bit stereo\n");
printf("%s 48000 16 2\n", argv[0]);
return 1;
}
int fs = atoi(argv[1]);
int bw = atoi(argv[2]);
int ch = atoi(argv[3]);
int target = fs * bw * ch;
int cclk = 100000000;
result_t res;
res.pclkdiv_idx = 3;
res.bitrate = 0;
res.x = 1;
res.y = 1;
for(;res.pclkdiv_idx >= 0; res.pclkdiv_idx--) {
double clk = (cclk / pclkdiv[res.pclkdiv_idx]);
for(res.y = 1; res.y < 256; res.y++) {
double clk_y = clk / (double)res.y;
// Note y must be greater than or equal to x.
for(res.x = 1; res.x <= res.y; res.x++) {
double clk_y_x_2 = (clk_y * (double)res.x) / 2.0;
for(res.bitrate = 0; res.bitrate < 65; res.bitrate++) {
double val = clk_y_x_2 / ((double)res.bitrate + 1.0);
res.err = _fabs(val - target);
if(res.err < best.err) best = res;
if(res.err == 0.0) {
goto found;
}
}
}
}
}
goto not_found;
found:
printf("Found:\n");
printf(" pclkdiv: %d\n", pclkdiv[res.pclkdiv_idx]);
printf(" bitrate: %d\n", res.bitrate);
printf(" x: %d\n", res.x);
printf(" y: %d\n", res.y);
return 0;
not_found:
printf("Not found - best was:\n");
printf(" pclkdiv: %d\n", pclkdiv[best.pclkdiv_idx]);
printf(" bitrate: %d\n", best.bitrate);
printf(" x: %d\n", best.x);
printf(" y: %d\n", best.y);
printf(" err: %f\n", best.err);
return 1;
}
|