ref: 0318503fc4d5742c7b3e2c3b1b04efbde4983d6b
dir: /util.c/
#include <u.h> #include <libc.h> int usensec = 0; static int b2i[255] = { ['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['a'] = 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ['k'] = 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, ['u'] = 30, 31, 32, 33, 34, 35, ['A'] = 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ['K'] = 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, ['U'] = 30, 31, 32, 33, 34, 35, }; static float notes[/* octave */]['g'-'A'+1 /* note */] = { #include "a440.h" }; int i36(uchar c) { return b2i[c]; } float note2freq(uchar note, uchar octave) { note -= 'A'; octave -= '0'; if (octave >= nelem(notes) || note >= nelem(notes[0])) return 0.0; return notes[octave][note]; } int pathopen(char *path, char *fmt, ...) { va_list arg; char *s; int fd; va_start(arg, fmt); s = vsmprint(fmt, arg); va_end(arg); if (s == nil || (path = smprint("%s/%s", path, s)) == nil) sysfatal("memory"); free(s); if ((fd = open(path, OWRITE)) < 0) fprint(2, "%s: %r\n", path); free(path); return fd; } /* * nsec() is wallclock and can be adjusted by timesync * so need to use cycles() instead, but fall back to * nsec() in case we can't * * "fasthz" is how many ticks there are in a second * can be read from /dev/time * * perhaps using RDTSCP is even better */ uvlong nanosec(void) { static uvlong fasthz, xstart; uvlong x, div; int f, n, i; char tmp[128], *e; if (fasthz == ~0ULL) return nsec() - xstart; if (fasthz == 0) { fasthz = ~0ULL; xstart = nsec(); if (usensec) return 0; if ((f = open("/dev/time", OREAD)) >= 0 && (n = read(f, tmp, sizeof(tmp)-1)) > 2) { tmp[n] = 0; e = tmp; for (i = 0; i < 3; i++) strtoll(e, &e, 10); if ((fasthz = strtoll(e, nil, 10)) < 1) fasthz = ~0ULL; else cycles(&xstart); } close(f); if (fasthz == ~0ULL) { fprint(2, "couldn't get fasthz, falling back to nsec()\n"); fprint(2, "you might want to disable aux/timesync\n"); return 0; } } cycles(&x); x -= xstart; for (div = 1000000000ULL; x < 0x1999999999999999ULL && div > 1 ; div /= 10ULL, x *= 10ULL); return x / (fasthz / div); }