Skip to content

Instantly share code, notes, and snippets.

@pamaury
Created May 16, 2013 09:16
Show Gist options
  • Save pamaury/5590501 to your computer and use it in GitHub Desktop.
Save pamaury/5590501 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
long nearest_freq(int freq, int mult, int hold, int *p_int, int *p_frac)
{
uint64_t num = 750000 ;
num *= mult << 13;
num /= freq * (hold + 1);
*p_int = num / (1 << 13);
*p_frac = num % (1 << 13);
num = 750000;
num *= (1 << 13) * mult;
num /= (*p_frac + (*p_int << 13)) * (hold + 1);
return num;
}
void best(long f)
{
long best_error = f;
long best_base_mult = 1;
long best_src_hold = 0;
for(int base_mult = 1; base_mult <= 4; base_mult *= 2)
{
printf("[base_mult = %d]\n", base_mult);
for(int src_hold = 0; src_hold < 8; src_hold++)
{
printf(" [src_hold = %d]\n", src_hold);
int src_int, src_frac;
long cf = nearest_freq(f, base_mult, src_hold, &src_int, &src_frac);
printf(" src=[%d, %d] cf = %ld Hz err = %d Hz\n",
src_int, src_frac, cf, abs(cf - f));
}
}
}
int main(int argc, char **argv)
{
if(argc != 2)
return 1;
long f = strtol(argv[1], NULL, 0);
printf("freq = %ld Hz\n", f);
int base_mult = 1;
int src_hold = 0;
if(f > 96000)
base_mult = 4;
else if(f > 48000)
base_mult = 2;
else if(f <= 12000)
src_hold = 3;
else if(f <= 24000)
src_hold = 1;
int src_int = (750000 * base_mult) / (f * (src_hold + 1));
int src_frac = ((750000 * base_mult - src_int * f * (src_hold + 1)) << 13) / (f * (src_hold + 1));
int res_f = ((750000LL << 13LL) * base_mult) / (((src_int << 13) + src_frac) * (src_hold + 1));
printf("base_mult = %d src_hold = %d src_int = %d src_frac = %d\n",
base_mult, src_hold, src_int, src_frac);
printf("result freq = %d error = %d\n", res_f, abs(res_f - f));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment