123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- /*
- Spectrum Analyzer
- */
- #include "Main.h"
- #include <math.h>
- #include "../nu/threadname.h"
- static int last_pos;
- typedef struct sa_l
- {
- int timestamp;
- unsigned char data[2*75];
- char which;
- } sa_l;
- static int sa_fps = 76;
- static sa_l *sa_bufs;
- static int sa_position;
- static int sa_length, sa_size;
- static CRITICAL_SECTION cs;
- void sa_init(int numframes)
- {
- EnterCriticalSection(&cs);
- sa_length=0;
- if (numframes < 1) numframes = 1;
- if (numframes > sa_size)
- {
- free(sa_bufs);
- sa_bufs = (sa_l *)calloc(numframes, sizeof(sa_l));
- sa_size=numframes;
- }
- sa_position = 0;
- sa_length = numframes;
- last_pos = 0;
- LeaveCriticalSection(&cs);
- }
- void sa_deinit(void)
- {
- EnterCriticalSection(&cs);
- //if (sa_bufs)
- // {
- // free(sa_bufs);
- // sa_bufs = 0;
- sa_length = 0;
- //}
- LeaveCriticalSection(&cs);
- }
- int sa_add(char *values, int timestamp, int csa)
- {
- EnterCriticalSection(&cs);
- if (!sa_bufs || sa_length == 0)
- {
- LeaveCriticalSection(&cs);
- return 1;
- }
- if (sa_length == 1)
- {
- sa_position = 0;
- }
- if (csa == 3) csa = 1; // dont let it happen unless it has a high bit set
- csa &= 0x7fffffff;
- sa_bufs[sa_position].timestamp = timestamp;
- sa_bufs[sa_position].which = (char)csa;
- if (csa & 1)
- {
- memcpy(sa_bufs[sa_position].data, values, 75);
- values += 75;
- }
- else
- memset(sa_bufs[sa_position].data, 0, 75);
- if (csa & 2)
- memcpy(sa_bufs[sa_position].data + 75, values, 75);
- else
- memset(sa_bufs[sa_position].data + 75, 0, 75);
- sa_position++;
- if (sa_position >= sa_length) sa_position -= sa_length;
- LeaveCriticalSection(&cs);
- return 0;
- }
- char *sa_get(int timestamp, int csa, char data[75*2+8])
- {
- static int sa_pos;
- int closest = 1000000, closest_v = -1;
- EnterCriticalSection(&cs);
- if (!sa_bufs || sa_length==0)
- {
- LeaveCriticalSection(&cs);
- return 0;
- }
- if (sa_length == 1)
- {
- memcpy(data, sa_bufs[0].data, 75*2);
- LeaveCriticalSection(&cs);
- return (data);
- }
- int i = last_pos;
- for (int x = 0; x < sa_length; x ++)
- {
- if (i >= sa_length) i = 0;
- int d = timestamp - sa_bufs[i].timestamp;
- if (d < 0) d = -d;
- if (d < closest)
- {
- closest = d;
- closest_v = i;
- }
- else if (closest <= 6) break;
- i++;
- }
- if (closest < 400 && closest_v >= 0 && sa_bufs[closest_v].which & csa)
- {
- sa_pos = 0;
- last_pos = closest_v;
- memcpy(data, sa_bufs[closest_v].data, 75*2);
- LeaveCriticalSection(&cs);
- return data;
- }
- if (closest_v < 0 || !(sa_bufs[closest_v].which & csa) || closest > 400)
- {
- memset(data, 0, 75);
- data[(sa_pos % 150) >= 75 ? 149 - (sa_pos % 150) : (sa_pos % 150)] = 15;
- for (int x = 0; x < 75; x ++)
- data[x + 75] = (char) (int) (7.0 * sin((sa_pos + x) * 0.1));
- sa_pos++;
- LeaveCriticalSection(&cs);
- return data;
- }
- LeaveCriticalSection(&cs);
- return 0;
- }
- volatile int sa_override;
- void export_sa_setreq(int want)
- {
- EnterCriticalSection(&cs);
- sa_override = want;
- LeaveCriticalSection(&cs);
- }
- char *export_sa_get_deprecated()
- {
- static char data[75*2 + 8];
- int now = in_getouttime();
- char *p = sa_get(now, 3, data);
- if (!p) memset(data, 0, 75*2);
- return data;
- }
- char *export_sa_get(char data[75*2 + 8])
- {
- try
- {
- int now = in_getouttime();
- char *p = sa_get(now, 3, data);
- if (!p) memset(data, 0, 75*2);
- }
- catch(...) {}
- return data;
- }
- #pragma optimize("", off) // for some reason, optimizations are breaking the case statement in bivis_thread
- #define KILL_EVENT 0
- #define BLANK_EVENT 1
- #define ON_EVENT 2
- #define NUM_EVENTS 3
- #define saKillEvent saEvents[0]
- #define saBlankEvent saEvents[1]
- #define saOnEvent saEvents[2]
- HANDLE saEvents[NUM_EVENTS] = {0};
- static int SA_Wait()
- {
- if (WaitForSingleObject(saKillEvent, 16) == WAIT_OBJECT_0)
- return KILL_EVENT;
- if (WaitForSingleObject(saBlankEvent, 0) == WAIT_OBJECT_0)
- return BLANK_EVENT;
- return WaitForMultipleObjects(NUM_EVENTS, saEvents, FALSE, INFINITE)-WAIT_OBJECT_0;
- }
- static DWORD WINAPI bivis_thread(void *none)
- {
- int cycleCount=0;
- __int8 data[75*2 + 8] = {0};
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
- SetThreadName((DWORD)-1, "Classic Viz");
- while (1)
- {
- switch(SA_Wait())
- {
- case KILL_EVENT:
- return 0;
- case BLANK_EVENT:
- draw_sa(NULL, 1);
- break;
- case ON_EVENT:
- {
- int draw=0;
- if (++cycleCount < config_saref)
- draw=0;
- else
- {
- cycleCount=0;
- draw=1;
- }
- if (config_sa
- && !paused
- && playing
- && !config_minimized
- && (config_mw_open || (config_pe_open && config_pe_width >= 350 && config_pe_height != 14))
- && (!config_disvis || !vis_running()))
- {
- int a = in_getouttime();
- int t = config_sa;
- //if ((config_windowshade&&config_mw_open) && t == 1) t=4;
- char *c = sa_get(a, t, data);
- if (c)
- {
- if (t == 2) c += 75;
- else memset(c + 75, 0, 4);
- draw_sa((unsigned char*)c, draw);
- }
- }
- }
- break;
- }
- }
- return 0;
- }
- #pragma optimize("", on)
- HANDLE saThread=0;
- void SpectralAnalyzer_Create()
- {
- DWORD threadId = 0;
- InitializeCriticalSection(&cs);
- saKillEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- saBlankEvent= CreateEvent(NULL, FALSE, FALSE, NULL);
- saOnEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- saThread = (HANDLE) CreateThread(NULL, 256*1024, (LPTHREAD_START_ROUTINE) bivis_thread, 0, 0, &threadId);
- //cut: done on thread - SetThreadPriority(saThread, THREAD_PRIORITY_HIGHEST);
- sa_length=sa_size=0;
- VU_Create();
- }
- void SpectralAnalyzer_Destroy()
- {
- VU_Destroy();
- SetEvent(saKillEvent);
- WaitForSingleObject(saThread, INFINITE);
- CloseHandle(saThread);
- saThread = 0;
- CloseHandle(saKillEvent);
- CloseHandle(saBlankEvent);
- CloseHandle(saOnEvent);
- DeleteCriticalSection(&cs);
- free(sa_bufs);
- sa_bufs=0;
- sa_size=0;
- }
- volatile int sa_curmode;
- /*
- @param mode -1==shutdown 0==none, 1==spectral analyzer, 2==oscilloscope
- */
- void sa_setthread(int mode)
- {
- if (mode == -1)
- mode=0;
- sa_curmode = mode;
- if (mode)
- {
- SetEvent(saOnEvent);
- }
- else
- {
- ResetEvent(saOnEvent);
- SetEvent(saBlankEvent);
- }
- }
|