make ColorChord work on Android.
This commit is contained in:
parent
241733ab9a
commit
79089566a1
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -7,3 +7,6 @@
|
||||||
[submodule "colorchord2/cnfa"]
|
[submodule "colorchord2/cnfa"]
|
||||||
path = colorchord2/cnfa
|
path = colorchord2/cnfa
|
||||||
url = https://github.com/cnlohr/cnfa
|
url = https://github.com/cnlohr/cnfa
|
||||||
|
[submodule "colorchord2/android/rawdrawandroid"]
|
||||||
|
path = colorchord2/android/rawdrawandroid
|
||||||
|
url = https://github.com/cnlohr/rawdrawandroid
|
||||||
|
|
|
@ -31,7 +31,7 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
||||||
int i;
|
int i;
|
||||||
float cw = ((float)(screenx)) / 2.0;
|
float cw = ((float)(screenx)) / 2.0;
|
||||||
float ch = ((float)(screeny)) / 2.0;
|
float ch = ((float)(screeny)) / 2.0;
|
||||||
RDPoint pts[4];
|
RDPoint pts[6];
|
||||||
float sizeA = sqrtf( screenx * screenx + screeny * screeny ) * d->pie_min;
|
float sizeA = sqrtf( screenx * screenx + screeny * screeny ) * d->pie_min;
|
||||||
float sizeB = sqrtf( screenx * screenx + screeny * screeny ) * d->pie_max;
|
float sizeB = sqrtf( screenx * screenx + screeny * screeny ) * d->pie_max;
|
||||||
for( i = 0; i < d->leds; i++ )
|
for( i = 0; i < d->leds; i++ )
|
||||||
|
@ -44,11 +44,16 @@ static void DPOUpdate(void * id, struct NoteFinder*nf)
|
||||||
pts[1].y = ch + sin(angA) * sizeB;
|
pts[1].y = ch + sin(angA) * sizeB;
|
||||||
pts[2].x = cw + cos(angB) * sizeB;
|
pts[2].x = cw + cos(angB) * sizeB;
|
||||||
pts[2].y = ch + sin(angB) * sizeB;
|
pts[2].y = ch + sin(angB) * sizeB;
|
||||||
pts[3].x = cw + cos(angB) * sizeA;
|
|
||||||
pts[3].y = ch + sin(angB) * sizeA;
|
pts[3].x = cw + cos(angA) * sizeA;
|
||||||
|
pts[3].y = ch + sin(angA) * sizeA;
|
||||||
|
pts[4].x = cw + cos(angB) * sizeB;
|
||||||
|
pts[4].y = ch + sin(angB) * sizeB;
|
||||||
|
pts[5].x = cw + cos(angB) * sizeA;
|
||||||
|
pts[5].y = ch + sin(angB) * sizeA;
|
||||||
|
|
||||||
CNFGColor( OutLEDs[i*3+0] | (OutLEDs[i*3+1] <<8)|(OutLEDs[i*3+2] <<16) );
|
CNFGColor( OutLEDs[i*3+0] | (OutLEDs[i*3+1] <<8)|(OutLEDs[i*3+2] <<16) );
|
||||||
CNFGTackPoly( pts, 4 );
|
CNFGTackPoly( pts, 6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,13 @@ LDLIBS:=-lpthread -lasound -lm -lpulse-simple -lpulse -ludev -lrt
|
||||||
CFLAGS:=-g -O1 -flto -Wall -ffast-math -I../embeddedcommon -I. -Icnfa -Irawdraw -DICACHE_FLASH_ATTR=
|
CFLAGS:=-g -O1 -flto -Wall -ffast-math -I../embeddedcommon -I. -Icnfa -Irawdraw -DICACHE_FLASH_ATTR=
|
||||||
EXTRALIBS:=-lusb-1.0
|
EXTRALIBS:=-lusb-1.0
|
||||||
|
|
||||||
OBJS:=os_generic.o 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
|
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 : $(OBJS)
|
colorchord : $(OBJS)
|
||||||
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
gcc -o $@ $^ $(CFLAGS) $(LDLIBS) $(EXTRALIBS) $(RAWDRAWLIBS)
|
||||||
|
|
||||||
|
|
||||||
colorchord.exe : os_generic.c 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
|
colorchord.exe : 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
|
||||||
$(WINGCC) $(WINGCCFLAGS) -o $@ $^ $(WINLDFLAGS)
|
$(WINGCC) $(WINGCCFLAGS) -o $@ $^ $(WINLDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
|
24
colorchord2/android/AndroidManifest.xml
Normal file
24
colorchord2/android/AndroidManifest.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" package="org.cnlohr.colorchord">
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
|
||||||
|
<application android:debuggable="true" android:hasCode="false" android:label="colorchord" tools:replace="android:icon,android:theme,android:allowBackup,label" android:icon="@mipmap/icon">
|
||||||
|
<activity android:configChanges="keyboardHidden|orientation" android:label="colorchord" android:name="android.app.NativeActivity">
|
||||||
|
|
||||||
|
<!-- This device filter seems to do nothing at all! If you figure out how to use it or what it does, let me know!! -->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.hardware.usb.action.ACTION_USB_DEVICE_ATTACHED" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data android:name="android.hardware.usb.action.ACTION_USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
|
||||||
|
|
||||||
|
<meta-data android:name="android.app.lib_name" android:value="colorchord"/>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
125
colorchord2/android/DisplayTensigralAndroid.c
Normal file
125
colorchord2/android/DisplayTensigralAndroid.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
#include "outdrivers.h"
|
||||||
|
#include "notefinder.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "parameters.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "color.h"
|
||||||
|
#include "CNFG.h"
|
||||||
|
#include "rawdrawandroid/android_usb_devices.h"
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/usbdevice_fs.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_LEDS_PER_NOTE 512
|
||||||
|
|
||||||
|
extern short screenx, screeny;
|
||||||
|
|
||||||
|
struct DTADriver
|
||||||
|
{
|
||||||
|
int leds;
|
||||||
|
};
|
||||||
|
|
||||||
|
char TensigralDebugStatus[8192];
|
||||||
|
|
||||||
|
int RequestPermissionOrGetConnectionFD( char * debug_status, uint16_t vid, uint16_t pid );
|
||||||
|
void DisconnectUSB(); //Disconnect from USB
|
||||||
|
|
||||||
|
extern jobject deviceConnection;
|
||||||
|
extern int deviceConnectionFD;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void DTAUpdate(void * id, struct NoteFinder*nf)
|
||||||
|
{
|
||||||
|
struct DTADriver * d = (struct DTADriver*)id;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if( deviceConnectionFD == 0 )
|
||||||
|
{
|
||||||
|
RequestPermissionOrGetConnectionFD( TensigralDebugStatus, 0xabcd, 0xf410 );
|
||||||
|
}
|
||||||
|
|
||||||
|
CNFGPenX = 800;
|
||||||
|
CNFGPenY = 800;
|
||||||
|
CNFGColor( 0xffffff );
|
||||||
|
CNFGDrawText( TensigralDebugStatus, 2 );
|
||||||
|
|
||||||
|
if( !deviceConnectionFD ) return;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t packet[64];
|
||||||
|
|
||||||
|
if( deviceConnectionFD )
|
||||||
|
{
|
||||||
|
//This section does the crazy wacky stuff to actually split the LEDs into HID Packets and get them out the door... Carefully.
|
||||||
|
int byrem = d->leds*4; //OutLEDs[i*3+1]
|
||||||
|
int offset = 0;
|
||||||
|
int marker = 0;
|
||||||
|
for( i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
uint8_t sendbuf[64];
|
||||||
|
sendbuf[0] = (byrem > 60)?15:(byrem/4);
|
||||||
|
sendbuf[1] = offset;
|
||||||
|
|
||||||
|
// memcpy( sendbuf + 2, Colorbuf + offset*4, sendbuf[0]*4 );
|
||||||
|
int j;
|
||||||
|
for( j = 0; j < sendbuf[0]; j++ )
|
||||||
|
{
|
||||||
|
sendbuf[j*4+3] = OutLEDs[marker++];
|
||||||
|
sendbuf[j*4+2] = OutLEDs[marker++];
|
||||||
|
sendbuf[j*4+4] = OutLEDs[marker++];
|
||||||
|
sendbuf[j*4+5] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += sendbuf[0];
|
||||||
|
byrem -= sendbuf[0]*4;
|
||||||
|
|
||||||
|
|
||||||
|
if( byrem == 0 ) sendbuf[0] |= 0x80;
|
||||||
|
int tsend = 65; //Size of payload (must be 64+1 always)
|
||||||
|
|
||||||
|
//Ok this looks weird, because Android has a bulkTransfer function, but that has a TON of layers of misdirection before it just calls the ioctl.
|
||||||
|
struct usbdevfs_bulktransfer ctrl;
|
||||||
|
memset(&ctrl, 0, sizeof(ctrl));
|
||||||
|
ctrl.ep = 0x02; //Endpoint 0x02 is output endpoint.
|
||||||
|
ctrl.len = 64;
|
||||||
|
ctrl.data = sendbuf;
|
||||||
|
ctrl.timeout = 100;
|
||||||
|
int lastFDWrite = ioctl(deviceConnectionFD, USBDEVFS_BULK, &ctrl);
|
||||||
|
if( lastFDWrite < 0 )
|
||||||
|
{
|
||||||
|
DisconnectUSB();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CNFGColor( 0xffffff );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DTAParams(void * id )
|
||||||
|
{
|
||||||
|
struct DTADriver * d = (struct DTADriver*)id;
|
||||||
|
|
||||||
|
d->leds = 9; RegisterValue( "leds", PAINT, &d->leds, sizeof( d->leds ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct DriverInstances * DisplayTensigralAndroid(const char * parameters)
|
||||||
|
{
|
||||||
|
struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) );
|
||||||
|
struct DTADriver * d = ret->id = malloc( sizeof( struct DTADriver ) );
|
||||||
|
memset( d, 0, sizeof( struct DTADriver ) );
|
||||||
|
ret->Func = DTAUpdate;
|
||||||
|
ret->Params = DTAParams;
|
||||||
|
DTAParams( d );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_OUT_DRIVER(DisplayTensigralAndroid);
|
||||||
|
|
||||||
|
|
16
colorchord2/android/Makefile
Normal file
16
colorchord2/android/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
APPNAME=colorchord
|
||||||
|
RAWDRAWANDROID=rawdrawandroid
|
||||||
|
PACKAGENAME?=org.cnlohr.$(APPNAME)
|
||||||
|
|
||||||
|
CFLAGS:=-I. -I.. -Irawdrawandroid/rawdraw -I../cnfa -I../../embeddedcommon -ffunction-sections -Os -DPRINTF_NO_OVERRIDDE
|
||||||
|
LDFLAGS:=-s -lOpenSLES
|
||||||
|
PACKAGENAME?=org.yourorgexample.$(APPNAME)
|
||||||
|
|
||||||
|
CC_C:= ../main.c ../dft.c ../decompose.c ../filter.c ../color.c ../notefinder.c ../util.c ../hook.c ../outdrivers.c ../parameters.c ../chash.c ../OutputVoronoi.c ../OutputProminent.c ../DisplayArray.c ../OutputLinear.c ../DisplayPie.c ../DisplayNetwork.c ../../embeddedcommon/DFT32.c ../OutputCells.c ../configs.c
|
||||||
|
|
||||||
|
SRC:=rawdrawandroid/android_usb_devices.c DisplayTensigralAndroid.c $(CC_C)
|
||||||
|
|
||||||
|
include rawdrawandroid/Makefile
|
||||||
|
|
||||||
|
|
2
colorchord2/android/README.md
Normal file
2
colorchord2/android/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
This part of the project is baed on https://github.com/cnlohr/androidusbtest
|
||||||
|
|
BIN
colorchord2/android/Sources/res/mipmap/icon.png
Normal file
BIN
colorchord2/android/Sources/res/mipmap/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
8
colorchord2/android/Sources/res/xml/device_filter.xml
Normal file
8
colorchord2/android/Sources/res/xml/device_filter.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- This file seems to do NOTHING AT ALL! If you have any idea how to use the device filters file, please let me know! -->
|
||||||
|
<resources>
|
||||||
|
<!-- <usb-device vendor-id="abcd" product-id="f410" /> --> <!-- class="3" subclass="255" protocol="255" -->
|
||||||
|
<usb-device vendor-id="43981" product-id="62480" />
|
||||||
|
</resources>
|
||||||
|
|
1
colorchord2/android/rawdrawandroid
Submodule
1
colorchord2/android/rawdrawandroid
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit a124feee8d928f2276c00a35c56e15b8d5984a06
|
392
colorchord2/android/test.c
Normal file
392
colorchord2/android/test.c
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
//Copyright (c) 2011-2020 <>< Charles Lohr - Under the MIT/x11 or NewBSD License you choose.
|
||||||
|
// NO WARRANTY! NO GUARANTEE OF SUPPORT! USE AT YOUR OWN RISK
|
||||||
|
// Super basic test - see rawdrawandroid's thing for a more reasonable test.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#include <asset_manager.h>
|
||||||
|
#include <asset_manager_jni.h>
|
||||||
|
#include <android_native_app_glue.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <android/sensor.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/usbdevice_fs.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#include "android_usb_devices.h"
|
||||||
|
|
||||||
|
#include "os_generic.h"
|
||||||
|
|
||||||
|
#define CNFG_IMPLEMENTATION
|
||||||
|
#include "CNFG.h"
|
||||||
|
|
||||||
|
#define printf( x...) LOGI( x )
|
||||||
|
|
||||||
|
unsigned frames = 0;
|
||||||
|
unsigned long iframeno = 0;
|
||||||
|
|
||||||
|
void AndroidDisplayKeyboard(int pShow);
|
||||||
|
volatile int suspended;
|
||||||
|
|
||||||
|
short screenx, screeny;
|
||||||
|
int lastmousex = 0;
|
||||||
|
int lastmousey = 0;
|
||||||
|
int lastbid = 0;
|
||||||
|
int lastmask = 0;
|
||||||
|
int lastkey, lastkeydown;
|
||||||
|
|
||||||
|
static int keyboard_up;
|
||||||
|
|
||||||
|
int mousedown;
|
||||||
|
int colormode;
|
||||||
|
double colormodechangetime;
|
||||||
|
|
||||||
|
|
||||||
|
void HandleKey( int keycode, int bDown )
|
||||||
|
{
|
||||||
|
lastkey = keycode;
|
||||||
|
lastkeydown = bDown;
|
||||||
|
if( keycode == 10 && !bDown ) { keyboard_up = 0; AndroidDisplayKeyboard( keyboard_up ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleButton( int x, int y, int button, int bDown )
|
||||||
|
{
|
||||||
|
lastbid = button;
|
||||||
|
lastmousex = x;
|
||||||
|
lastmousey = y;
|
||||||
|
|
||||||
|
if( bDown ) { colormode = (colormode+1)%2; }
|
||||||
|
if( !bDown ) { colormodechangetime = OGGetAbsoluteTime(); }
|
||||||
|
mousedown = bDown;
|
||||||
|
// if( bDown ) { keyboard_up = !keyboard_up; AndroidDisplayKeyboard( keyboard_up ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleMotion( int x, int y, int mask )
|
||||||
|
{
|
||||||
|
lastmask = mask;
|
||||||
|
lastmousex = x;
|
||||||
|
lastmousey = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct android_app * gapp;
|
||||||
|
|
||||||
|
int lastFDWrite = 0;
|
||||||
|
|
||||||
|
void HandleDestroy()
|
||||||
|
{
|
||||||
|
printf( "Destroying\n" );
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleSuspend()
|
||||||
|
{
|
||||||
|
suspended = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleResume()
|
||||||
|
{
|
||||||
|
suspended = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_LEDS 20
|
||||||
|
uint8_t Colorbuf[NUM_LEDS*4];
|
||||||
|
|
||||||
|
char rettext[512];
|
||||||
|
char assettext[512];
|
||||||
|
|
||||||
|
int pixelhueX = -1, pixelhueY = -1;
|
||||||
|
|
||||||
|
unsigned long HSVtoHEX( float hue, float sat, float value );
|
||||||
|
unsigned long PixelHue( int x, int y )
|
||||||
|
{
|
||||||
|
float sat = (pixelhueY-y) / (float)pixelhueY * 2.0;
|
||||||
|
float hue = x / (float)pixelhueX;
|
||||||
|
if( sat < 1.0 )
|
||||||
|
{
|
||||||
|
return HSVtoHEX( x * 0.0012, (sat<1)?sat:1, 1.0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return HSVtoHEX( x * 0.0012, (sat<1)?sat:1, 2.0-sat );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int i, x, y;
|
||||||
|
double ThisTime;
|
||||||
|
double LastFPSTime = OGGetAbsoluteTime();
|
||||||
|
double LastFrameTime = OGGetAbsoluteTime();
|
||||||
|
double SecToWait;
|
||||||
|
int linesegs = 0;
|
||||||
|
uint32_t * pixelHueBackdrop = 0;
|
||||||
|
|
||||||
|
CNFGBGColor = 0x400000;
|
||||||
|
CNFGDialogColor = 0x444444;
|
||||||
|
CNFGSetup( "Test Bench", 0, 0 );
|
||||||
|
|
||||||
|
//To make text look boldish
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int i, pos;
|
||||||
|
float f;
|
||||||
|
iframeno++;
|
||||||
|
RDPoint pto[3];
|
||||||
|
|
||||||
|
CNFGHandleInput();
|
||||||
|
|
||||||
|
if( suspended ) { usleep(50000); continue; }
|
||||||
|
|
||||||
|
CNFGClearFrame();
|
||||||
|
CNFGGetDimensions( &screenx, &screeny );
|
||||||
|
|
||||||
|
if( ( screenx != pixelhueX || screeny != pixelhueY ) && screenx > 0 && screeny > 0)
|
||||||
|
{
|
||||||
|
pixelhueX = screenx;
|
||||||
|
pixelhueY = screeny;
|
||||||
|
pixelHueBackdrop = realloc( pixelHueBackdrop, pixelhueX * pixelhueY * 4 );
|
||||||
|
int x, y;
|
||||||
|
for( y = 0; y < pixelhueY; y++ )
|
||||||
|
for( x = 0; x < pixelhueX; x++ )
|
||||||
|
{
|
||||||
|
pixelHueBackdrop[x+y*screenx] = PixelHue( x, y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//This whole section does cool stuff with LEDs
|
||||||
|
int allledbytes = NUM_LEDS*4;
|
||||||
|
for( i = 0; i < allledbytes; i+=4 )
|
||||||
|
{
|
||||||
|
uint32_t rk;
|
||||||
|
float sat = (OGGetAbsoluteTime() - colormodechangetime)*3.0;
|
||||||
|
|
||||||
|
if( colormode )
|
||||||
|
{
|
||||||
|
rk = PixelHue( lastmousex, lastmousey );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rk = HSVtoHEX( i * 0.012+ iframeno* .01, (sat<1)?sat:1, 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int white = (int)((1.-sat) * 255);
|
||||||
|
if( white > 255 ) white = 255;
|
||||||
|
if( white < 0 ) white = 0;
|
||||||
|
|
||||||
|
Colorbuf[i+0] = rk>>8;
|
||||||
|
Colorbuf[i+1] = rk;
|
||||||
|
Colorbuf[i+2] = rk>>16;
|
||||||
|
Colorbuf[i+3] = white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( pixelHueBackdrop && colormode == 1 && mousedown )
|
||||||
|
{
|
||||||
|
CNFGUpdateScreenWithBitmap( pixelHueBackdrop, pixelhueX, pixelhueY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int led = 0;
|
||||||
|
for( led = 0; led < NUM_LEDS; led++ )
|
||||||
|
{
|
||||||
|
uint32_t col = ( Colorbuf[led*4+0] << 8) | ( Colorbuf[led*4+1] ) | ( Colorbuf[led*4+2] << 16);
|
||||||
|
CNFGColor( 0xff000000 | col );
|
||||||
|
int sx = (led * screenx) / (NUM_LEDS);
|
||||||
|
CNFGTackRectangle( sx, 850, sx + screenx/(NUM_LEDS)+1, screeny );
|
||||||
|
CNFGFlushRender();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( deviceConnectionFD )
|
||||||
|
{
|
||||||
|
//This section does the crazy wacky stuff to actually split the LEDs into HID Packets and get them out the door... Carefully.
|
||||||
|
int byrem = allledbytes;
|
||||||
|
int offset = 0;
|
||||||
|
for( i = 0; i < 2; i++ )
|
||||||
|
{
|
||||||
|
uint8_t sendbuf[64];
|
||||||
|
sendbuf[0] = (byrem > 60)?15:(byrem/4);
|
||||||
|
sendbuf[1] = offset;
|
||||||
|
|
||||||
|
memcpy( sendbuf + 2, Colorbuf + offset*4, sendbuf[0]*4 );
|
||||||
|
|
||||||
|
offset += sendbuf[0];
|
||||||
|
byrem -= sendbuf[0]*4;
|
||||||
|
|
||||||
|
|
||||||
|
if( byrem == 0 ) sendbuf[0] |= 0x80;
|
||||||
|
int tsend = 65; //Size of payload (must be 64+1 always)
|
||||||
|
|
||||||
|
//Ok this looks weird, because Android has a bulkTransfer function, but that has a TON of layers of misdirection before it just calls the ioctl.
|
||||||
|
struct usbdevfs_bulktransfer ctrl;
|
||||||
|
memset(&ctrl, 0, sizeof(ctrl));
|
||||||
|
ctrl.ep = 0x02; //Endpoint 0x02 is output endpoint.
|
||||||
|
ctrl.len = 64;
|
||||||
|
ctrl.data = sendbuf;
|
||||||
|
ctrl.timeout = 100;
|
||||||
|
lastFDWrite = ioctl(deviceConnectionFD, USBDEVFS_BULK, &ctrl);
|
||||||
|
if( lastFDWrite < 0 )
|
||||||
|
{
|
||||||
|
DisconnectUSB();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char * rxprintf = rettext;
|
||||||
|
uint8_t RXbuf[64];
|
||||||
|
//Also read-back the properties.
|
||||||
|
struct usbdevfs_bulktransfer ctrl;
|
||||||
|
memset(&ctrl, 0, sizeof(ctrl));
|
||||||
|
ctrl.ep = 0x81; //Endpoint 0x81 is input endpoint.
|
||||||
|
ctrl.len = 64;
|
||||||
|
ctrl.data = RXbuf;
|
||||||
|
ctrl.timeout = 100;
|
||||||
|
int lastfdread = ioctl(deviceConnectionFD, USBDEVFS_BULK, &ctrl);
|
||||||
|
rxprintf += sprintf( rxprintf, "RX: %d\n", lastfdread );
|
||||||
|
if( lastfdread == 64 )
|
||||||
|
{
|
||||||
|
int temperature = RXbuf[4] | (RXbuf[5]<<8);
|
||||||
|
int adc = RXbuf[6] | (RXbuf[7]<<8);
|
||||||
|
int voltage = RXbuf[8] | (RXbuf[9]<<8);
|
||||||
|
rxprintf += sprintf( rxprintf, "T: %d ADC: %d V: %d\n", temperature, adc, voltage );
|
||||||
|
|
||||||
|
int t;
|
||||||
|
CNFGColor( 0xffffffff );
|
||||||
|
for( t = 0; t < 3; t++ )
|
||||||
|
{
|
||||||
|
CNFGTackSegment( t * screenx / 3, RXbuf[20+t] * 50 + 1100, (t+1)*screenx/3, RXbuf[20+t] * 50 + 1100 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( deviceConnectionFD == 0 )
|
||||||
|
{
|
||||||
|
RequestPermissionOrGetConnectionFD( assettext, 0xabcd, 0xf410 );
|
||||||
|
}
|
||||||
|
|
||||||
|
CNFGPenX = 20; CNFGPenY = 200;
|
||||||
|
char st[2048];
|
||||||
|
sprintf( st, "%dx%d %d %d %d %d - %d %d - %d\n%s\n%s", screenx, screeny, lastmousex, lastmousey, lastkey, lastkeydown, lastbid, lastmask, lastFDWrite, assettext, rettext );
|
||||||
|
|
||||||
|
CNFGColor( 0xff000000 );
|
||||||
|
glLineWidth( 20.0f );
|
||||||
|
CNFGDrawText( st, 10 );
|
||||||
|
CNFGFlushRender();
|
||||||
|
|
||||||
|
CNFGColor( 0xFFFFFFFF );
|
||||||
|
glLineWidth( 2.0f );
|
||||||
|
CNFGDrawText( st, 10 );
|
||||||
|
CNFGFlushRender();
|
||||||
|
|
||||||
|
|
||||||
|
// Square behind text
|
||||||
|
|
||||||
|
frames++;
|
||||||
|
CNFGSwapBuffers();
|
||||||
|
|
||||||
|
ThisTime = OGGetAbsoluteTime();
|
||||||
|
if( ThisTime > LastFPSTime + 1 )
|
||||||
|
{
|
||||||
|
printf( "FPS: %d\n", frames );
|
||||||
|
frames = 0;
|
||||||
|
linesegs = 0;
|
||||||
|
LastFPSTime+=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long HSVtoHEX( float hue, float sat, float value )
|
||||||
|
{
|
||||||
|
float pr = 0;
|
||||||
|
float pg = 0;
|
||||||
|
float pb = 0;
|
||||||
|
|
||||||
|
short ora = 0;
|
||||||
|
short og = 0;
|
||||||
|
short ob = 0;
|
||||||
|
|
||||||
|
float ro = fmod( hue * 6, 6. );
|
||||||
|
|
||||||
|
float avg = 0;
|
||||||
|
|
||||||
|
ro = fmod( ro + 6 + 1, 6 ); //Hue was 60* off...
|
||||||
|
|
||||||
|
if( ro < 1 ) //yellow->red
|
||||||
|
{
|
||||||
|
pr = 1;
|
||||||
|
pg = 1. - ro;
|
||||||
|
} else if( ro < 2 )
|
||||||
|
{
|
||||||
|
pr = 1;
|
||||||
|
pb = ro - 1.;
|
||||||
|
} else if( ro < 3 )
|
||||||
|
{
|
||||||
|
pr = 3. - ro;
|
||||||
|
pb = 1;
|
||||||
|
} else if( ro < 4 )
|
||||||
|
{
|
||||||
|
pb = 1;
|
||||||
|
pg = ro - 3;
|
||||||
|
} else if( ro < 5 )
|
||||||
|
{
|
||||||
|
pb = 5 - ro;
|
||||||
|
pg = 1;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
pg = 1;
|
||||||
|
pr = ro - 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Actually, above math is backwards, oops!
|
||||||
|
pr *= value;
|
||||||
|
pg *= value;
|
||||||
|
pb *= value;
|
||||||
|
|
||||||
|
avg += pr;
|
||||||
|
avg += pg;
|
||||||
|
avg += pb;
|
||||||
|
|
||||||
|
pr = pr * sat + avg * (1.-sat);
|
||||||
|
pg = pg * sat + avg * (1.-sat);
|
||||||
|
pb = pb * sat + avg * (1.-sat);
|
||||||
|
|
||||||
|
ora = pr * 255;
|
||||||
|
og = pb * 255;
|
||||||
|
ob = pg * 255;
|
||||||
|
|
||||||
|
if( ora < 0 ) ora = 0;
|
||||||
|
if( ora > 255 ) ora = 255;
|
||||||
|
if( og < 0 ) og = 0;
|
||||||
|
if( og > 255 ) og = 255;
|
||||||
|
if( ob < 0 ) ob = 0;
|
||||||
|
if( ob > 255 ) ob = 255;
|
||||||
|
|
||||||
|
return (ob<<16) | (og<<8) | ora;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 22f0e58a4df57c6a6b5fa05665a6d454e597e2da
|
Subproject commit c474fb4c0a81a3d460125ce275c5dc7d96eba0b5
|
Binary file not shown.
|
@ -96,8 +96,8 @@ void SetEnvValues( int force )
|
||||||
SetParametersFromString( "outdrivers=OutputVoronoi,DisplayArray" );
|
SetParametersFromString( "outdrivers=OutputVoronoi,DisplayArray" );
|
||||||
SetParametersFromString( "note_attach_amp_iir2=0.250" );
|
SetParametersFromString( "note_attach_amp_iir2=0.250" );
|
||||||
|
|
||||||
SetParametersFromString( "lightx=64" );
|
SetParametersFromString( "lightx=32" );
|
||||||
SetParametersFromString( "lighty=32" );
|
SetParametersFromString( "lighty=60" );
|
||||||
SetParametersFromString( "fromsides=1" );
|
SetParametersFromString( "fromsides=1" );
|
||||||
SetParametersFromString( "shape_cutoff=0.03" );
|
SetParametersFromString( "shape_cutoff=0.03" );
|
||||||
|
|
||||||
|
@ -105,7 +105,9 @@ void SetEnvValues( int force )
|
||||||
SetParametersFromString( "amppow=2.510" );
|
SetParametersFromString( "amppow=2.510" );
|
||||||
SetParametersFromString( "distpow=1.500" );
|
SetParametersFromString( "distpow=1.500" );
|
||||||
|
|
||||||
#else
|
printf( "On Android, looking for configuration file in: %s\n", InitialFile[0] );
|
||||||
|
#endif
|
||||||
|
|
||||||
LoadFile( InitialFile[0] );
|
LoadFile( InitialFile[0] );
|
||||||
|
|
||||||
for( i = 1; i < gargc; i++ )
|
for( i = 1; i < gargc; i++ )
|
||||||
|
@ -121,7 +123,6 @@ void SetEnvValues( int force )
|
||||||
LoadFile( gargv[i] );
|
LoadFile( gargv[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessArgs()
|
void ProcessArgs()
|
||||||
|
@ -145,9 +146,11 @@ void ProcessArgs()
|
||||||
|
|
||||||
void SetupConfigs()
|
void SetupConfigs()
|
||||||
{
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
InitialFile[0] = "/sdcard/colorchord-android.conf";
|
||||||
|
#else
|
||||||
InitialFile[0] = "default.conf";
|
InitialFile[0] = "default.conf";
|
||||||
|
#endif
|
||||||
|
|
||||||
ProcessArgs();
|
ProcessArgs();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,14 +41,23 @@ struct CNFADriver * sd;
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
static int pfd[2];
|
static int pfd[2];
|
||||||
static pthread_t loggingThread;
|
static pthread_t loggingThread;
|
||||||
static const char *LOG_TAG = "colorchord";
|
static const char *LOG_TAG = "colorchord";
|
||||||
|
|
||||||
|
char genlog[16384] = "log";
|
||||||
|
char * genlogptr;
|
||||||
|
|
||||||
static void *loggingFunction(void*v) {
|
static void *loggingFunction(void*v) {
|
||||||
ssize_t readSize;
|
ssize_t readSize;
|
||||||
char buf[128];
|
char buf[1024];
|
||||||
|
static og_mutex_t m;
|
||||||
|
if( !m ) m = OGCreateMutex();
|
||||||
|
|
||||||
|
|
||||||
while((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
|
while((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
|
||||||
|
OGLockMutex( m );
|
||||||
if(buf[readSize - 1] == '\n') {
|
if(buf[readSize - 1] == '\n') {
|
||||||
--readSize;
|
--readSize;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +65,45 @@ static void *loggingFunction(void*v) {
|
||||||
buf[readSize] = 0; // add null-terminator
|
buf[readSize] = 0; // add null-terminator
|
||||||
|
|
||||||
__android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, buf); // Set any log level you want
|
__android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, buf); // Set any log level you want
|
||||||
|
if( genlogptr == 0 ) genlogptr = genlog;
|
||||||
|
int genlogbuffer = genlogptr - genlog;
|
||||||
|
if( genlogbuffer + readSize + 1 < sizeof( genlog ) )
|
||||||
|
{
|
||||||
|
memcpy( genlogptr, buf, readSize );
|
||||||
|
genlogptr += readSize;
|
||||||
|
*genlogptr = '\n';
|
||||||
|
genlogptr++;
|
||||||
|
*genlogptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scroll lines.
|
||||||
|
|
||||||
|
#define KEEPLINES 80
|
||||||
|
int lineplaces[KEEPLINES];
|
||||||
|
int newlinect = 0;
|
||||||
|
genlogbuffer = genlogptr - genlog;
|
||||||
|
int i;
|
||||||
|
for( i = 0; i < genlogbuffer; i++ )
|
||||||
|
{
|
||||||
|
if( genlog[i] == '\n' )
|
||||||
|
{
|
||||||
|
lineplaces[newlinect%KEEPLINES] = i;
|
||||||
|
newlinect++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( newlinect >= KEEPLINES )
|
||||||
|
{
|
||||||
|
int placemark = lineplaces[(newlinect+1)%KEEPLINES];
|
||||||
|
for( i = placemark; i <= genlogbuffer; i++ )
|
||||||
|
{
|
||||||
|
genlog[i-placemark] = genlog[i];
|
||||||
|
}
|
||||||
|
genlogptr -= placemark;
|
||||||
|
}
|
||||||
|
|
||||||
|
OGUnlockMutex( m );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -97,8 +145,14 @@ char sound_source[16]; REGISTER_PARAM( sound_source, PABUFFER );
|
||||||
int cpu_autolimit = 1; REGISTER_PARAM( cpu_autolimit, PAINT );
|
int cpu_autolimit = 1; REGISTER_PARAM( cpu_autolimit, PAINT );
|
||||||
float cpu_autolimit_interval = 0.016; REGISTER_PARAM( cpu_autolimit_interval, PAFLOAT );
|
float cpu_autolimit_interval = 0.016; REGISTER_PARAM( cpu_autolimit_interval, PAFLOAT );
|
||||||
int sample_channel = -1;REGISTER_PARAM( sample_channel, PAINT );
|
int sample_channel = -1;REGISTER_PARAM( sample_channel, PAINT );
|
||||||
int showfps = 0; REGISTER_PARAM( showfps, PAINT );
|
int showfps = 1; REGISTER_PARAM( showfps, PAINT );
|
||||||
float in_amplitude = 1; REGISTER_PARAM( in_amplitude, PAFLOAT );
|
|
||||||
|
#if defined(ANDROID) || defined( __android__ )
|
||||||
|
float in_amplitude = 2;
|
||||||
|
#else
|
||||||
|
float in_amplitude = 1;
|
||||||
|
#endif
|
||||||
|
REGISTER_PARAM( in_amplitude, PAFLOAT );
|
||||||
|
|
||||||
struct NoteFinder * nf;
|
struct NoteFinder * nf;
|
||||||
|
|
||||||
|
@ -115,14 +169,19 @@ int show_debug_basic = 1;
|
||||||
int gKey = 0;
|
int gKey = 0;
|
||||||
extern int force_white;
|
extern int force_white;
|
||||||
|
|
||||||
|
void RecalcBaseHz()
|
||||||
|
{
|
||||||
|
nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf );
|
||||||
|
}
|
||||||
|
|
||||||
void HandleKey( int keycode, int bDown )
|
void HandleKey( int keycode, int bDown )
|
||||||
{
|
{
|
||||||
char c = toupper( keycode );
|
char c = toupper( keycode );
|
||||||
if( c == 'D' && bDown ) show_debug = !show_debug;
|
if( c == 'D' && bDown ) show_debug = !show_debug;
|
||||||
if( c == 'W' ) force_white = bDown;
|
if( c == 'W' ) force_white = bDown;
|
||||||
if( c == '9' && bDown ) { gKey--; nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf ); }
|
if( c == '9' && bDown ) { gKey--; RecalcBaseHz(); }
|
||||||
if( c == '-' && bDown ) { gKey++; nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf ); }
|
if( c == '-' && bDown ) { gKey++; RecalcBaseHz(); }
|
||||||
if( c == '0' && bDown ) { gKey = 0; nf->base_hz = 55 * pow( 2, gKey / 12.0 ); ChangeNFParameters( nf ); }
|
if( c == '0' && bDown ) { gKey = 0; RecalcBaseHz(); }
|
||||||
if( c == 'E' && bDown ) show_debug_basic = !show_debug_basic;
|
if( c == 'E' && bDown ) show_debug_basic = !show_debug_basic;
|
||||||
if( c == 'K' && bDown ) DumpParameters();
|
if( c == 'K' && bDown ) DumpParameters();
|
||||||
if( keycode == ESCAPE_KEY ) exit( 0 );
|
if( keycode == ESCAPE_KEY ) exit( 0 );
|
||||||
|
@ -133,6 +192,26 @@ void HandleKey( int keycode, int bDown )
|
||||||
void HandleButton( int x, int y, int button, int bDown )
|
void HandleButton( int x, int y, int button, int bDown )
|
||||||
{
|
{
|
||||||
printf( "Button: %d,%d (%d) -> %d\n", x, y, button, bDown );
|
printf( "Button: %d,%d (%d) -> %d\n", x, y, button, bDown );
|
||||||
|
if( bDown )
|
||||||
|
{
|
||||||
|
if( y < 800 )
|
||||||
|
{
|
||||||
|
if( x < screenx/3 )
|
||||||
|
{
|
||||||
|
gKey --;
|
||||||
|
}
|
||||||
|
else if( x < (screenx*2/3) )
|
||||||
|
{
|
||||||
|
gKey = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gKey++;
|
||||||
|
}
|
||||||
|
printf( "KEY: %d\n", gKey );
|
||||||
|
RecalcBaseHz();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMotion( int x, int y, int mask )
|
void HandleMotion( int x, int y, int mask )
|
||||||
|
@ -202,7 +281,7 @@ void SoundCB( struct CNFADriver * sd, short * in, short * out, int samplesr, int
|
||||||
{
|
{
|
||||||
out[j] = 0;
|
out[j] = 0;
|
||||||
}
|
}
|
||||||
SoundEventHappened( samplesr, out, 1, sd->channelsPlay );
|
SoundEventHappened( samplesp, out, 1, channelout );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,6 +303,7 @@ int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
setvbuf(stdout, 0, _IOLBF, 0); // make stdout line-buffered
|
setvbuf(stdout, 0, _IOLBF, 0); // make stdout line-buffered
|
||||||
setvbuf(stderr, 0, _IONBF, 0); // make stderr unbuffered
|
setvbuf(stderr, 0, _IONBF, 0); // make stderr unbuffered
|
||||||
|
@ -233,6 +313,9 @@ int main(int argc, char ** argv)
|
||||||
dup2(pfd[1], 1);
|
dup2(pfd[1], 1);
|
||||||
dup2(pfd[1], 2);
|
dup2(pfd[1], 2);
|
||||||
|
|
||||||
|
genlogptr = genlog;
|
||||||
|
*genlogptr = 0;
|
||||||
|
|
||||||
/* spawn the logging thread */
|
/* spawn the logging thread */
|
||||||
if(pthread_create(&loggingThread, 0, loggingFunction, 0) == -1) {
|
if(pthread_create(&loggingThread, 0, loggingFunction, 0) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -260,6 +343,14 @@ int main(int argc, char ** argv)
|
||||||
strcpy( sound_source, "WIN" );
|
strcpy( sound_source, "WIN" );
|
||||||
#elif defined( ANDROID )
|
#elif defined( ANDROID )
|
||||||
strcpy( sound_source, "ANDROID" );
|
strcpy( sound_source, "ANDROID" );
|
||||||
|
|
||||||
|
int hasperm = AndroidHasPermissions( "READ_EXTERNAL_STORAGE" );
|
||||||
|
if( !hasperm )
|
||||||
|
{
|
||||||
|
AndroidRequestAppPermissions( "READ_EXTERNAL_STORAGE" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy( sound_source, "PULSE" );
|
strcpy( sound_source, "PULSE" );
|
||||||
#endif
|
#endif
|
||||||
|
@ -324,22 +415,31 @@ int main(int argc, char ** argv)
|
||||||
free(OutDriverNames);
|
free(OutDriverNames);
|
||||||
|
|
||||||
|
|
||||||
//Initialize Sound
|
do
|
||||||
sd = CNFAInit( sound_source, "colorchord", &SoundCB, GetParameterI( "samplerate", 44100 ),
|
|
||||||
GetParameterI( "channels", 2 ), GetParameterI( "channels", 2 ), GetParameterI( "buffer", 1024 ),
|
|
||||||
GetParameterS( "devrecord", 0 ), GetParameterS( "devplay", 0 ) );
|
|
||||||
|
|
||||||
if( !sd )
|
|
||||||
{
|
{
|
||||||
fprintf( stderr, "ERROR: Failed to initialize sound output device\n" );
|
//Initialize Sound
|
||||||
return -1;
|
sd = CNFAInit( sound_source, "colorchord", &SoundCB, GetParameterI( "samplerate", 44100 ),
|
||||||
}
|
GetParameterI( "channels", 2 ), GetParameterI( "channels", 2 ), GetParameterI( "buffer", 1024 ),
|
||||||
|
GetParameterS( "devrecord", 0 ), GetParameterS( "devplay", 0 ) );
|
||||||
|
|
||||||
|
if( sd ) break;
|
||||||
|
|
||||||
|
CNFGColor( 0xffffff );
|
||||||
|
CNFGPenX = 10; CNFGPenY = 100;
|
||||||
|
CNFGHandleInput();
|
||||||
|
CNFGClearFrame();
|
||||||
|
CNFGDrawText( "Colorchord must be used with sound. Sound not available.", 10 );
|
||||||
|
CNFGSwapBuffers();
|
||||||
|
sleep(1);
|
||||||
|
} while( 1 );
|
||||||
|
|
||||||
nf = CreateNoteFinder( sd->sps );
|
nf = CreateNoteFinder( sd->sps );
|
||||||
|
|
||||||
//Once everything was reinitialized, re-read the ini files.
|
//Once everything was reinitialized, re-read the ini files.
|
||||||
SetEnvValues( 1 );
|
SetEnvValues( 1 );
|
||||||
|
|
||||||
|
printf( "================================================= Set Up\n" );
|
||||||
|
|
||||||
Now = OGGetAbsoluteTime();
|
Now = OGGetAbsoluteTime();
|
||||||
double Last = Now;
|
double Last = Now;
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -500,6 +600,13 @@ int main(int argc, char ** argv)
|
||||||
CNFGPenX = 440; CNFGPenY = screeny-10;
|
CNFGPenX = 440; CNFGPenY = screeny-10;
|
||||||
sprintf( stt, "FPS: %d", lastfps );
|
sprintf( stt, "FPS: %d", lastfps );
|
||||||
CNFGDrawText( stt, 2 );
|
CNFGDrawText( stt, 2 );
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
CNFGColor( 0xffffff );
|
||||||
|
CNFGPenX = 10; CNFGPenY = 600;
|
||||||
|
CNFGDrawText( genlog, 3 );
|
||||||
|
#endif
|
||||||
|
|
||||||
CNFGSwapBuffers();
|
CNFGSwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +616,9 @@ int main(int argc, char ** argv)
|
||||||
ThisTime = OGGetAbsoluteTime();
|
ThisTime = OGGetAbsoluteTime();
|
||||||
if( ThisTime > LastFPSTime + 1 && showfps )
|
if( ThisTime > LastFPSTime + 1 && showfps )
|
||||||
{
|
{
|
||||||
|
#ifndef ANDROID
|
||||||
printf( "FPS: %d\n", frames );
|
printf( "FPS: %d\n", frames );
|
||||||
|
#endif
|
||||||
lastfps = frames;
|
lastfps = frames;
|
||||||
frames = 0;
|
frames = 0;
|
||||||
LastFPSTime+=1;
|
LastFPSTime+=1;
|
||||||
|
@ -530,3 +639,5 @@ int main(int argc, char ** argv)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,343 +0,0 @@
|
||||||
//Copyright 2015 <>< Charles Lohr under the NewBSD OR MIT/x11 License.
|
|
||||||
|
|
||||||
#include "os_generic.h"
|
|
||||||
|
|
||||||
#ifdef USE_WINDOWS
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
void OGSleep( int is )
|
|
||||||
{
|
|
||||||
Sleep( is*1000 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGUSleep( int ius )
|
|
||||||
{
|
|
||||||
Sleep( ius/1000 );
|
|
||||||
}
|
|
||||||
|
|
||||||
double OGGetAbsoluteTime()
|
|
||||||
{
|
|
||||||
static LARGE_INTEGER lpf;
|
|
||||||
LARGE_INTEGER li;
|
|
||||||
|
|
||||||
if( !lpf.QuadPart )
|
|
||||||
{
|
|
||||||
QueryPerformanceFrequency( &lpf );
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryPerformanceCounter( &li );
|
|
||||||
return (double)li.QuadPart / (double)lpf.QuadPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double OGGetFileTime( const char * file )
|
|
||||||
{
|
|
||||||
FILETIME ft;
|
|
||||||
|
|
||||||
HANDLE h = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
|
|
||||||
if( h==INVALID_HANDLE_VALUE )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
GetFileTime( h, 0, 0, &ft );
|
|
||||||
|
|
||||||
CloseHandle( h );
|
|
||||||
|
|
||||||
return ft.dwHighDateTime + ft.dwLowDateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter )
|
|
||||||
{
|
|
||||||
return (og_thread_t)CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)routine, parameter, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void * OGJoinThread( og_thread_t ot )
|
|
||||||
{
|
|
||||||
WaitForSingleObject( ot, INFINITE );
|
|
||||||
CloseHandle( ot );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGCancelThread( og_thread_t ot )
|
|
||||||
{
|
|
||||||
CloseHandle( ot );
|
|
||||||
}
|
|
||||||
|
|
||||||
og_mutex_t OGCreateMutex()
|
|
||||||
{
|
|
||||||
return CreateMutex( 0, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLockMutex( og_mutex_t om )
|
|
||||||
{
|
|
||||||
WaitForSingleObject(om, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGUnlockMutex( og_mutex_t om )
|
|
||||||
{
|
|
||||||
ReleaseMutex(om);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGDeleteMutex( og_mutex_t om )
|
|
||||||
{
|
|
||||||
CloseHandle( om );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
og_sema_t OGCreateSema()
|
|
||||||
{
|
|
||||||
HANDLE sem = CreateSemaphore( 0, 0, 32767, 0 );
|
|
||||||
return (og_sema_t)sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OGGetSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
typedef LONG NTSTATUS;
|
|
||||||
HANDLE sem = (HANDLE)os;
|
|
||||||
typedef NTSTATUS (NTAPI *_NtQuerySemaphore)(
|
|
||||||
HANDLE SemaphoreHandle,
|
|
||||||
DWORD SemaphoreInformationClass, /* Would be SEMAPHORE_INFORMATION_CLASS */
|
|
||||||
PVOID SemaphoreInformation, /* but this is to much to dump here */
|
|
||||||
ULONG SemaphoreInformationLength,
|
|
||||||
PULONG ReturnLength OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef struct _SEMAPHORE_BASIC_INFORMATION {
|
|
||||||
ULONG CurrentCount;
|
|
||||||
ULONG MaximumCount;
|
|
||||||
} SEMAPHORE_BASIC_INFORMATION;
|
|
||||||
|
|
||||||
|
|
||||||
static _NtQuerySemaphore NtQuerySemaphore;
|
|
||||||
SEMAPHORE_BASIC_INFORMATION BasicInfo;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if( !NtQuerySemaphore )
|
|
||||||
{
|
|
||||||
NtQuerySemaphore = (_NtQuerySemaphore)GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQuerySemaphore");
|
|
||||||
if( !NtQuerySemaphore )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Status = NtQuerySemaphore (sem, 0 /*SemaphoreBasicInformation*/,
|
|
||||||
&BasicInfo, sizeof (SEMAPHORE_BASIC_INFORMATION), NULL);
|
|
||||||
|
|
||||||
if (Status == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
return BasicInfo.CurrentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLockSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
WaitForSingleObject( (HANDLE)os, INFINITE );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGUnlockSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
ReleaseSemaphore( (HANDLE)os, 1, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGDeleteSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
CloseHandle( os );
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <semaphore.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
pthread_mutex_t g_RawMutexStart = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
void OGSleep( int is )
|
|
||||||
{
|
|
||||||
sleep( is );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGUSleep( int ius )
|
|
||||||
{
|
|
||||||
usleep( ius );
|
|
||||||
}
|
|
||||||
|
|
||||||
double OGGetAbsoluteTime()
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday( &tv, 0 );
|
|
||||||
return ((double)tv.tv_usec)/1000000. + (tv.tv_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
double OGGetFileTime( const char * file )
|
|
||||||
{
|
|
||||||
struct stat buff;
|
|
||||||
|
|
||||||
int r = stat( file, &buff );
|
|
||||||
|
|
||||||
if( r < 0 )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return buff.st_mtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter )
|
|
||||||
{
|
|
||||||
pthread_t * ret = malloc( sizeof( pthread_t ) );
|
|
||||||
int r = pthread_create( ret, 0, routine, parameter );
|
|
||||||
if( r )
|
|
||||||
{
|
|
||||||
free( ret );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (og_thread_t)ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * OGJoinThread( og_thread_t ot )
|
|
||||||
{
|
|
||||||
void * retval;
|
|
||||||
if( !ot )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pthread_join( *(pthread_t*)ot, &retval );
|
|
||||||
free( ot );
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGCancelThread( og_thread_t ot )
|
|
||||||
{
|
|
||||||
if( !ot )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef ANDROID
|
|
||||||
void * fakeret;
|
|
||||||
pthread_join( *(pthread_t*)ot, &fakeret );
|
|
||||||
#else
|
|
||||||
pthread_cancel( *(pthread_t*)ot );
|
|
||||||
#endif
|
|
||||||
free( ot );
|
|
||||||
}
|
|
||||||
|
|
||||||
og_mutex_t OGCreateMutex()
|
|
||||||
{
|
|
||||||
pthread_mutexattr_t mta;
|
|
||||||
og_mutex_t r = malloc( sizeof( pthread_mutex_t ) );
|
|
||||||
|
|
||||||
pthread_mutexattr_init(&mta);
|
|
||||||
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
|
|
||||||
|
|
||||||
pthread_mutex_init( (pthread_mutex_t *)r, &mta );
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLockMutex( og_mutex_t om )
|
|
||||||
{
|
|
||||||
if( !om )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pthread_mutex_lock( (pthread_mutex_t*)om );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGUnlockMutex( og_mutex_t om )
|
|
||||||
{
|
|
||||||
if( !om )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock( (pthread_mutex_t*)om );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGDeleteMutex( og_mutex_t om )
|
|
||||||
{
|
|
||||||
if( !om )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_destroy( (pthread_mutex_t*)om );
|
|
||||||
free( om );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
og_sema_t OGCreateSema()
|
|
||||||
{
|
|
||||||
sem_t * sem = malloc( sizeof( sem_t ) );
|
|
||||||
sem_init( sem, 0, 0 );
|
|
||||||
return (og_sema_t)sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OGGetSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
int valp;
|
|
||||||
sem_getvalue( os, &valp );
|
|
||||||
return valp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OGLockSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
sem_wait( os );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGUnlockSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
sem_post( os );
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGDeleteSema( og_sema_t os )
|
|
||||||
{
|
|
||||||
sem_destroy( os );
|
|
||||||
free(os);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Date Stamp: 2012-02-15
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2011-2012 <>< Charles Lohr
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of this file.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
//Copyright 2015 <>< Charles Lohr under the NewBSD or MIT/x11 License.
|
|
||||||
#ifndef _OS_GENERIC_H
|
|
||||||
#define _OS_GENERIC_H
|
|
||||||
|
|
||||||
#if defined( WIN32 ) || defined (WINDOWS) || defined( _WIN32)
|
|
||||||
#define USE_WINDOWS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//Things that shouldn't be macro'd
|
|
||||||
double OGGetAbsoluteTime();
|
|
||||||
void OGSleep( int is );
|
|
||||||
void OGUSleep( int ius );
|
|
||||||
double OGGetFileTime( const char * file );
|
|
||||||
|
|
||||||
//Threads and Mutices
|
|
||||||
typedef void* og_thread_t;
|
|
||||||
typedef void* og_mutex_t;
|
|
||||||
typedef void* og_sema_t;
|
|
||||||
|
|
||||||
og_thread_t OGCreateThread( void * (routine)( void * ), void * parameter );
|
|
||||||
void * OGJoinThread( og_thread_t ot );
|
|
||||||
void OGCancelThread( og_thread_t ot );
|
|
||||||
|
|
||||||
//Always a recrusive mutex.
|
|
||||||
og_mutex_t OGCreateMutex();
|
|
||||||
void OGLockMutex( og_mutex_t om );
|
|
||||||
void OGUnlockMutex( og_mutex_t om );
|
|
||||||
void OGDeleteMutex( og_mutex_t om );
|
|
||||||
|
|
||||||
//Always a semaphore
|
|
||||||
og_sema_t OGCreateSema(); //Create a semaphore, comes locked initially. NOTE: Max count is 32767
|
|
||||||
void OGLockSema( og_sema_t os );
|
|
||||||
int OGGetSema( og_sema_t os ); //if <0 there was a failure.
|
|
||||||
void OGUnlockSema( og_sema_t os );
|
|
||||||
void OGDeleteSema( og_sema_t os );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//Date Stamp: 2012-02-15
|
|
||||||
|
|
||||||
/*
|
|
||||||
NOTE: Portions (namely the top section) are part of headers from other
|
|
||||||
sources.
|
|
||||||
|
|
||||||
Copyright (c) 2011-2012 <>< Charles Lohr
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
copy of this software and associated documentation files (the "Software"),
|
|
||||||
to deal in the Software without restriction, including without limitation
|
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of this file.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 55fa52d1eb355baf1456aa55251e722500a32ab8
|
Subproject commit 407da6d1e7a11e68565c4f8cb35dfc330167e30b
|
Loading…
Reference in a new issue