Merge pull request #105 from CaiB/master

Add official WASAPI support to colorchord
This commit is contained in:
CNLohr 2020-05-20 22:07:09 -07:00 committed by GitHub
commit a4dd3dc4e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 252 additions and 77 deletions

4
.gitignore vendored
View file

@ -1,3 +1,7 @@
colorchord2/windows/colorchord.def
colorchord2/colorchord.def
*.o
**/*.exp
**/*.ilk
**/*.pdb
colorchord2/colorchord.lib

View file

@ -58,6 +58,8 @@ make
Building with Windows
-------------------
There are 3 options available for building on Windows, MSYS2, clang, or TCC.
### MSYS2
With either 64bit or 32bit [MSYS2](https://msys2.github.io/) installed, run the _MSYS2 MSYS_ launcher and use `pacman` to set up a MinGW32 toolchain, if you don't have one already:
```
pacman -S mingw-w64-i686-toolchain
@ -71,6 +73,26 @@ To make colorchord, navigate to your working copy and type:
mingw32-make colorchord.exe
```
### clang
Start by [downloading](https://clang.llvm.org/) the clang compiler, and installing it.
Edit the batch script at `colorchord2/windows/compile-clang.bat`:
- Verify that the executable location is correct, on line 1 (`CC`).
If you have the Windows SDK installed, you should not need to do any additional work.
If you do not, you'll want to either [install it](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk/) to get the official headers, or use the unofficial headers instead by adding `-DNO_WIN_HEADERS` to the `CCFLAGS` line in the batch file above.
Run the batch script, and it should output to `colorchord2/colorchord.exe`.
### TCC
Start by [downloading TCC](http://savannah.nongnu.org/projects/tinycc/), and extracting it to a location of your choice.
Edit the batch script at `colorchord2/windows/compile.bat`:
- Edit line 17 (`CC`) to be the location where you put TCC. If there are spaces in the path, wrap the entire path in quotes.
Note that TCC is not able to use the Windows SDK, and as such using the unofficial headers is required, and automatically enabled when compiling with TCC. If you encounter issues, try the clang method above instead.
Using
-----

View file

@ -126,7 +126,8 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
{
float sat = nf->note_amplitudes_out[bestmatch] * d->satamp;
if( sat > 1.0 ) sat = 1.0;
color = CCtoHEX( nf->note_positions[bestmatch] / nf->freqbins, 1.0, sat );
float note_color = nf->note_positions[bestmatch] / nf->freqbins;
color = CCtoHEX( note_color, 1.0, sat );
}
OutLEDs[led*3+0] = color & 0xff;

View file

@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.SET_RELEASE_APP"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application android:debuggable="false" android:hasCode="false" android:label="colorchord" tools:replace="android:icon,android:theme,android:allowBackup,label" android:icon="@mipmap/icon" > <!--android:requestLegacyExternalStorage="true" Not needed til Android 29 -->
<activity android:configChanges="keyboardHidden|orientation" android:label="colorchord" android:name="android.app.NativeActivity">

0
colorchord2/android/colorchord-android.txt Executable file → Normal file
View file

@ -1 +1 @@
Subproject commit 77d3e699fa304462af1a39414deeaac9c24f4131
Subproject commit c9700f455e17ff3db9bb509c3f4cb54edfff81b0

View file

@ -10,6 +10,13 @@
#include <stdio.h>
#include <malloc.h>
#if defined(WINDOWS) || defined(WIN32) || defined(WIN64) \
|| defined(_WIN32) || defined(_WIN64)
#ifndef strdup
#define strdup _strdup
#endif
#endif
#define I_AM_LITTLE (((union { unsigned x; unsigned char c; }){1}).c)
static unsigned long GetStrHash( const char * c )

@ -1 +1 @@
Subproject commit 15c95d49771c237b90b878b5ced163de575d9406
Subproject commit 9153df275e6fadfa0e2de9cdc5b49a1d858c950b

View file

@ -9,23 +9,23 @@ uint32_t CCtoHEX( float note, float sat, float value )
{
float hue = 0.0;
note = fmodf( note, 1.0 );
note *= 12;
if( note < 4 )
note *= 12.0;
if( note < 4.0 )
{
//Needs to be YELLOW->RED
hue = (4 - note) / 24.0;
hue = (4.0 - note) / 24.0;
}
else if( note < 8 )
else if( note < 8.0 )
{
// [4] [8]
//Needs to be RED->BLUE
hue = ( 4 - note ) / 12.0;
hue = ( 4.0 - note ) / 12.0;
}
else
{
// [8] [12]
//Needs to be BLUE->YELLOW
hue = ( 12 - note ) / 8.0 + 1./6.;
hue = ( 12.0 - note ) / 8.0 + 1.0/6.0;
}
return HSVtoHEX( hue, sat, value );
}
@ -41,44 +41,44 @@ uint32_t CCtoHEX( float note, float sat, float value )
uint32_t HSVtoHEX( float hue, float sat, float value )
{
float pr = 0;
float pg = 0;
float pb = 0;
float pr = 0.0;
float pg = 0.0;
float pb = 0.0;
short ora = 0;
short og = 0;
short ob = 0;
short ora = 0.0;
short og = 0.0;
short ob = 0.0;
float ro = fmod( hue * 6, 6. );
float ro = fmod( hue * 6.0, 6.0 );
float avg = 0;
float avg = 0.0;
ro = fmod( ro + 6 + 1, 6 ); //Hue was 60* off...
ro = fmod( ro + 6.0 + 1.0, 6.0 ); //Hue was 60* off...
if( ro < 1 ) //yellow->red
if( ro < 1.0 ) //yellow->red
{
pr = 1;
pg = 1. - ro;
} else if( ro < 2 )
pr = 1.0;
pg = 1.0 - ro;
} else if( ro < 2.0 )
{
pr = 1;
pb = ro - 1.;
} else if( ro < 3 )
pr = 1.0;
pb = ro - 1.0;
} else if( ro < 3.0 )
{
pr = 3. - ro;
pb = 1;
} else if( ro < 4 )
pr = 3.0 - ro;
pb = 1.0;
} else if( ro < 4.0 )
{
pb = 1;
pg = ro - 3;
} else if( ro < 5 )
pb = 1.0;
pg = ro - 3.0;
} else if( ro < 5.0 )
{
pb = 5 - ro;
pg = 1;
pb = 5.0 - ro;
pg = 1.0;
} else
{
pg = 1;
pr = ro - 5;
pg = 1.0;
pr = ro - 5.0;
}
//Actually, above math is backwards, oops!
@ -90,9 +90,9 @@ uint32_t HSVtoHEX( float hue, float sat, float value )
avg += pg;
avg += pb;
pr = pr * sat + avg * (1.-sat);
pg = pg * sat + avg * (1.-sat);
pb = pb * sat + avg * (1.-sat);
pr = pr * sat + avg * (1.0-sat);
pg = pg * sat + avg * (1.0-sat);
pb = pb * sat + avg * (1.0-sat);
ora = pr * 255;
og = pb * 255;

View file

@ -31,12 +31,12 @@ void LoadFile( const char * filename )
int size = ftell( f );
fseek( f, 0, SEEK_SET );
buffer = malloc( size + 1 );
r = fread( buffer, size, 1, f );
r = fread( buffer, 1, size, f);
fclose( f );
buffer[size] = 0;
if( r != 1 )
if( r != size )
{
fprintf( stderr, "Warning: %d bytes read. Expected: %d from file %s\n", r, size, filename );
fprintf( stderr, "Warning: %d bytes read. Expected: %d from file %s\n", r, size, filename );
}
else
{

View file

@ -22,15 +22,21 @@ wininput = -1
#Compiled version will default this.
#sound_source = ALSA
#-1 indicates left and right, 0 left, 1 right.
#-1 indicates left and right, 0 left, 1 right.
sample_channel = -1
sourcename = default
#alsa_output.pci-0000_00_1f.3.analog-stereo.monitor
#default
# Sets the playback device for CNFA (what speakers to go to)
devplay = default
# Sets the device to get audio from, for WASAPI, "default" searches for a mic
# devrecord = default
# For WASAPI, if speaker loopback is desired use the following line
devrecord = defaultRender
# For Linux mostly use the following command to find valid devices to read from:
# pactl list | grep pci- | grep monitor
# alsa_output.pci-0000_00_1f.3.analog-stereo.monitor
# alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
#alsa_output.pci-0000_00_1f.3.analog-stereo.monitor << New laptop
#use pactl list | grep pci- | grep monitor
# alsa_output.pci-0000_00_1f.3.analog-stereo.monitor << New laptop
##################################
# General ColorChord properties. #
@ -41,7 +47,7 @@ amplify = 2.0
# What is the base note? I.e. the lowest note.
# Note that it won't have very much impact until an octave up though!
base_hz = 55
base_hz = 55
# This is only used when dealing with the slow decompose (now defunct)
# decompose_iterations = 1000
@ -66,7 +72,7 @@ filter_iter = 2
filter_strength = .5
# How many bins per octave to use?
freqbins = 24
freqbins = 24
# For the final note information... How much to slack everything?
note_attach_amp_iir = 0.3500
@ -88,8 +94,8 @@ note_out_chop = 0.05000
#Outputs
This is a vornoi thing:
outdrivers = OutputVoronoi, DisplayArray
# This is a vornoi thing:
# outdrivers = OutputVoronoi, DisplayArray
lightx = 64
lighty = 32
fromsides = 1
@ -98,5 +104,12 @@ satamp = 5.000
amppow = 2.510
distpow = 1.500
outdrivers = DisplayArray, OutputLinear
# outdrivers = DisplayPie, OutputLinear
leds = 64
pie_min = 0.18
pie_max = 0.3

View file

@ -58,6 +58,13 @@ typedef LONG NTSTATUS;
/*#define HIDAPI_USE_DDK*/
#if defined(WINDOWS) || defined(WIN32) || defined(WIN64) \
|| defined(_WIN32) || defined(_WIN64)
#ifndef strdup
#define strdup _strdup
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -1,9 +1,14 @@
//Copyright 2015 <>< Charles Lohr under the ColorChord License.
#if defined(WIN32) || defined(USE_WINDOWS)
#if defined(WINDOWS) || defined(USE_WINDOWS)\
|| defined(WIN32) || defined(WIN64) \
|| defined(_WIN32) || defined(_WIN64)
#include <winsock2.h>
#include <windows.h>
#ifndef strdup
#define strdup _strdup
#endif
#endif
#include <ctype.h>
#include "color.h"
@ -143,9 +148,9 @@ int set_screenx = 640; REGISTER_PARAM( set_screenx, PAINT );
int set_screeny = 480; REGISTER_PARAM( set_screeny, PAINT );
char sound_source[16]; REGISTER_PARAM( sound_source, PABUFFER );
int cpu_autolimit = 1; REGISTER_PARAM( cpu_autolimit, PAINT );
float cpu_autolimit_interval = 0.016; REGISTER_PARAM( cpu_autolimit_interval, PAFLOAT );
int sample_channel = -1;REGISTER_PARAM( sample_channel, PAINT );
int showfps = 1; REGISTER_PARAM( showfps, PAINT );
float cpu_autolimit_interval = 0.016; REGISTER_PARAM( cpu_autolimit_interval, PAFLOAT );
int sample_channel = -1; REGISTER_PARAM( sample_channel, PAINT );
int showfps = 1; REGISTER_PARAM( showfps, PAINT );
#if defined(ANDROID) || defined( __android__ )
float in_amplitude = 2;
@ -308,13 +313,56 @@ void HandleResume()
}
#endif
// function for calling initilization functions if we are using TCC
#ifdef TCC
void RegisterConstructorFunctions(){
// Basic Window stuff
REGISTERheadless();
REGISTERset_screenx();
REGISTERset_screeny();
REGISTERsound_source();
REGISTERcpu_autolimit();
REGISTERcpu_autolimit_interval();
REGISTERsample_channel();
REGISTERshowfps();
REGISTERin_amplitude();
// Audio stuff
REGISTERNullCNFA();
REGISTERWinCNFA();
REGISTERcnfa_wasapi();
// Video Stuff
REGISTERnull();
REGISTERDisplayArray();
//REGISTERDisplayDMX();
//REGISTERDisplayFileWrite();
REGISTERDisplayHIDAPI();
REGISTERDisplayNetwork();
REGISTERDisplayOutDriver();
REGISTERDisplayPie();
//REGISTERDisplaySHM();
// Output stuff
//REGISTERDisplayUSB2812();
REGISTEROutputCells();
REGISTEROutputLinear();
REGISTEROutputProminent();
REGISTEROutputVoronoi();
//REGISTERRecorderPlugin();
//void ManuallyRegisterDevices();
//ManuallyRegisterDevices();
}
#endif
int main(int argc, char ** argv)
{
int i;
#ifdef TCC
void ManuallyRegisterDevices();
ManuallyRegisterDevices();
RegisterConstructorFunctions();
#endif
printf( "Output Drivers:\n" );
@ -327,7 +375,8 @@ int main(int argc, char ** argv)
WSAStartup(0x202, &wsaData);
strcpy( sound_source, "WIN" );
strcpy( sound_source, "WASAPI" ); // Use either "sound_source=WASAPI" or "sound_source=WIN" in config file.
#elif defined( ANDROID )
strcpy( sound_source, "ANDROID" );
@ -336,6 +385,11 @@ int main(int argc, char ** argv)
{
AndroidRequestAppPermissions( "READ_EXTERNAL_STORAGE" );
}
int haspermInternet = AndroidHasPermissions( "INTERNET" );
if( !haspermInternet )
{
AndroidRequestAppPermissions( "INTERNET" );
}
#else
@ -405,9 +459,11 @@ int main(int argc, char ** argv)
do
{
//Initialize Sound
sd = CNFAInit( sound_source, "colorchord", &SoundCB, GetParameterI( "samplerate", 44100 ),
GetParameterI( "channels", 2 ), GetParameterI( "channels", 2 ), GetParameterI( "buffer", 1024 ),
GetParameterS( "devrecord", 0 ), GetParameterS( "devplay", 0 ), 0 );
sd = CNFAInit( sound_source, "colorchord", &SoundCB,
GetParameterI( "samplerate", 44100 ), GetParameterI( "samplerate", 44100 ),
GetParameterI( "channels", 2 ), GetParameterI( "channels", 2 ),
GetParameterI( "buffer", 1024 ),
GetParameterS( "devrecord", 0 ), GetParameterS( "devplay", 0 ), NULL );
if( sd ) break;
@ -415,12 +471,12 @@ int main(int argc, char ** argv)
CNFGPenX = 10; CNFGPenY = 100;
CNFGHandleInput();
CNFGClearFrame();
CNFGDrawText( "Colorchord must be used with sound. Sound not available.", 10 );
CNFGDrawText( "Colorchord must be used with sound. Sound not available.", 10 );
CNFGSwapBuffers();
sleep(1);
OGSleep(1);
} while( 1 );
nf = CreateNoteFinder( sd->sps );
nf = CreateNoteFinder( sd->spsRec );
//Once everything was reinitialized, re-read the ini files.
SetEnvValues( 1 );
@ -429,7 +485,11 @@ int main(int argc, char ** argv)
Now = OGGetAbsoluteTime();
double Last = Now;
while( !bQuitColorChord )
#ifdef ANDROID
while(!bQuitColorChord)
#else
while(!headless)
#endif
{
char stt[1024];
//Handle Rawdraw frame swappign
@ -506,7 +566,8 @@ int main(int argc, char ** argv)
{
//printf( "%f %f /", note_positions[i], note_amplitudes[i] );
if( nf->note_amplitudes_out[i] < 0 ) continue;
CNFGDialogColor = CCtoHEX( (nf->note_positions[i] / freqbins), 1.0, 1.0 );
float note = (float) nf->note_positions[i] / freqbins;
CNFGDialogColor = CCtoHEX( note, 1.0, 1.0 );
CNFGDrawBox( ((float)i / note_peaks) * screenx, 480 - nf->note_amplitudes_out[i] * 100, ((float)(i+1) / note_peaks) * screenx, 480 );
CNFGPenX = ((float)(i+.4) / note_peaks) * screenx;
CNFGPenY = screeny - 30;
@ -629,6 +690,3 @@ int main(int argc, char ** argv)
}
}

View file

@ -7,6 +7,13 @@
#include <stdio.h>
#include <stdlib.h>
#if defined(WINDOWS) || defined(WIN32) || defined(WIN64) \
|| defined(_WIN32) || defined(_WIN64)
#ifndef strdup
#define strdup _strdup
#endif
#endif
int force_white = 0;
unsigned char OutLEDs[MAX_LEDS*3];
int UsedLEDs;

View file

@ -37,7 +37,7 @@ extern struct OutDriverListElem ODList[MAX_OUT_DRIVERS];
extern const char OutDriverParameters[MAX_OUT_DRIVER_STRING];
//Pass setup "name=[driver]"
struct DriverInstances * SetupOutDriver( );
struct DriverInstances * SetupOutDriver( const char * drivername );
void RegOutDriver( const char * ron, struct DriverInstances * (*Init)( ) );
#define REGISTER_OUT_DRIVER( name ) \

View file

@ -6,6 +6,13 @@
#include <stdio.h>
#include <stdlib.h>
#if defined(WINDOWS) || defined(WIN32) || defined(WIN64) \
|| defined(_WIN32) || defined(_WIN64)
#ifndef strdup
#define strdup _strdup
#endif
#endif
static struct chash * parameters;
//XXX TODO: Make this thread safe.

View file

@ -0,0 +1,24 @@
all : ../colorchord.exe
OUTS := OutputVoronoi.o DisplayArray.o OutputLinear.o DisplayPie.o DisplayNetwork.o DisplayUSB2812.o DisplayDMX.o OutputProminent.o RecorderPlugin.o DisplayHIDAPI.o hidapi.o OutputCells.o DisplaySHM.o DisplayFileWrite.o
SRCS := ../main.c ../dft.c ../decompose.c ../filter.c ../color.c ../notefinder.c ../util.c ../outdrivers.c
SRCS += ../parameters.c ../chash.c ../OutputVoronoi.c ../OutputProminent.c ../DisplayArray.c
SRCS += ../OutputLinear.c ../DisplayPie.c ../DisplayNetwork.c ../hook.c ../RecorderPlugin.c
SRCS += ../../embeddedcommon/DFT32.c ../OutputCells.c ../configs.c ../hidapi.c ../DisplayHIDAPI.c
WINGCC:= clang -fcolor-diagnostics
WINGCCFLAGS:= -g -D_CRT_SECURE_NO_WARNINGS -Wno-deprecated-declarations -DICACHE_FLASH_ATTR= -I../../embeddedcommon -I../cnfa -I../rawdraw -I../ -O1 #-O2 -Wl,--relax -Wl,--gc-sections -ffunction-sections -fdata-sections
WINLDFLAGS:=-lwinmm -lgdi32 -lws2_32 -lsetupapi -lkernel32 -luser32 -ldbghelp -lole32 -lmmdevapi -lAvrt
RAWDRAWLIBS:=-lX11 -lm -lpthread -lXinerama -lXext
LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse -ludev -lrt
OBJS:=../main.o ../dft.o ../decompose.o ../filter.o ../color.o ../notefinder.o ../util.o ../outdrivers.o $(OUTS) ../parameters.o ../chash.o ../hook.o ../../embeddedcommon/DFT32.o ../configs.o
../colorchord.exe : $(SRCS)
$(WINGCC) $(WINGCCFLAGS) -o $@ $^ $(WINLDFLAGS)
clean :
rm -rf *.o *~ ../colorchord ../colorchord.exe ../embeddedcc $(OBJS)

View file

@ -0,0 +1,13 @@
@echo off
set CC="C:\Program Files\LLVM\bin\clang.exe"
rem To enable OpenGL rendering use the -DCNFGOGL option
set CCFLAGS=-g -D_CRT_SECURE_NO_WARNINGS
set CCIFLAGS=-I../../embeddedcommon -I../cnfa -I../rawdraw -I../ -O2
set CCLFLAGS=-lwinmm -lgdi32 -lws2_32 -lsetupapi -lkernel32 -luser32 -ldbghelp -lole32 -lmmdevapi -lAvrt
set SOURCES=../main.c ../dft.c ../decompose.c ../filter.c ../color.c ../notefinder.c ../util.c ../outdrivers.c ^
../parameters.c ../chash.c ../OutputVoronoi.c ../OutputProminent.c ../DisplayArray.c ^
../OutputLinear.c ../DisplayPie.c ../DisplayNetwork.c ../hook.c ../RecorderPlugin.c ^
../../embeddedcommon/DFT32.c ../OutputCells.c ../configs.c ../hidapi.c ../DisplayHIDAPI.c
@echo on
%CC% %CCFLAGS% %CCIFLAGS% -o ../colorchord.exe %SOURCES% %CCLFLAGS%

View file

@ -1,12 +1,23 @@
@echo off
echo Unzip http://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27-win64-bin.zip to C:\tcc
echo Don't worry. It includes the i386 compiler in the win64 build.
set CFLAGS=-v -DHIDAPI -DWINDOWS -DWIN32 -DTCC -DRUNTIME_SYMNUM -Os -Itccinc -DINCLUDING_EMBEDDED -I../rawdraw -I../cnfa -I.. -I. -I../../embeddedcommon -rdynamic -g
set LDFLAGS=-lkernel32 -lgdi32 -luser32 -lsetupapi -ldbghelp -lws2_32
set SOURCES=..\chash.c ..\color.c ..\configs.c ..\decompose.c ..\dft.c ..\DisplayNetwork.c ..\DisplayArray.c ..\DisplayHIDAPI.c ..\DisplayOUTDriver.c ..\DisplayPie.c ..\filter.c ..\hidapi.c ..\hook.c ..\main.c ..\outdrivers.c ..\OutputCells.c ..\OutputLinear.c ..\OutputProminent.c ..\OutputVoronoi.c ..\parameters.c ..\util.c ..\notefinder.c ..\..\embeddedcommon\DFT32.c tcc_stubs.c symbol_enumerator.c
set ARCH_SPECIFIC=-L32 C:\windows\system32\winmm.dll
set CC=C:\tcc\i386-win32-tcc.exe
set CFLAGS= -v -DHIDAPI -DWINDOWS -DWIN32 -DTCC -DRUNTIME_SYMNUM -O2 -Itccinc -DINCLUDING_EMBEDDED -rdynamic -g
set INCLUDES=-I../rawdraw -I../cnfa -I.. -I. -I../../embeddedcommon
set LDFLAGS=-lkernel32 -lole32 -lgdi32 -luser32 -lsetupapi -ldbghelp -lws2_32 -lAvrt
rem lots of source files
set SOURCES=..\main.c ..\chash.c ..\color.c ..\configs.c ..\decompose.c ..\dft.c ..\filter.c ^
..\outdrivers.c ..\hidapi.c ..\hook.c ..\parameters.c ..\util.c ..\notefinder.c ^
..\..\embeddedcommon\DFT32.c tcc_stubs.c symbol_enumerator.c ^
..\DisplayNetwork.c ..\DisplayArray.c ..\DisplayHIDAPI.c ..\DisplayOUTDriver.c ..\DisplayPie.c ^
..\OutputCells.c ..\OutputLinear.c ..\OutputProminent.c ..\OutputVoronoi.c
set ARCH_SPECIFIC=-L32 C:\windows\system32\winmm.dll -DWIN32_LEAN_AND_MEAN
set CC=C:\tcc\tcc.exe
rem set CC=C:\tcc\i386-win32-tcc.exe
rem set CC=C:\tcc\x86_64-win32-tcc.exe
@echo on
%CC% %CFLAGS% %ARCH_SPECIFIC% %SOURCES% %LDFLAGS% -o ..\colorchord.exe
pause
%CC% %CFLAGS% %INCLUDES% %ARCH_SPECIFIC% %SOURCES% %LDFLAGS% -o ..\colorchord.exe
@echo off
pause