Commit 1dd1cd0c authored by Dave Griffiths's avatar Dave Griffiths
Browse files

moved src

parent 106ae09c
#include <jni.h>
#include <sys/time.h>
#include <time.h>
#include <android/log.h>
#include <stdint.h>
#include <stdio.h>
#include "scheme/scheme.h"
static int sWindowWidth = 320;
static int sWindowHeight = 480;
void Java_foam_starwisp_Scheme_nativeInit(JNIEnv* env)
{
appInit();
}
/* Call to initialize the graphics state */
void Java_foam_starwisp_Scheme_nativeInitGL( JNIEnv* env )
{
importGLInit();
initGL();
}
void Java_foam_starwisp_Scheme_nativeResize( JNIEnv* env, jobject thiz, jint w, jint h )
{
sWindowWidth = w;
sWindowHeight = h;
__android_log_print(ANDROID_LOG_INFO, "SanAngeles", "resize w=%d h=%d", w, h);
}
void Java_foam_starwisp_Scheme_nativeDone(JNIEnv* env)
{
appDeinit();
importGLDeinit();
}
void Java_foam_starwisp_Scheme_nativeRender( JNIEnv* env )
{
appRender(sWindowWidth, sWindowHeight);
}
jstring Java_foam_starwisp_Scheme_nativeEval(JNIEnv* env, jobject thiz, jstring code)
{
const char *native_code = (*env)->GetStringUTFChars(env, code, 0);
appEval(native_code);
(*env)->ReleaseStringUTFChars(env, code, native_code);
if (starwisp_data!=NULL) {
jstring ret = (*env)->NewStringUTF(env,starwisp_data);
free(starwisp_data);
starwisp_data=NULL;
return ret;
}
return (*env)->NewStringUTF(env,"");
}
void Java_foam_starwisp_Scheme_nativeLoadTexture(JNIEnv* env, jobject thiz, jstring texname, jbyteArray arr, jint w, jint h)
{
char *data = (char *) (*env)->GetByteArrayElements(env,arr,NULL);
int len = (*env)->GetArrayLength(env, arr);
const char *filename = (*env)->GetStringUTFChars(env, texname, 0);
__android_log_print(ANDROID_LOG_INFO, "starwisp", "loading texture");
int id=appLoadTexture(filename,w,h,data);
__android_log_print(ANDROID_LOG_INFO, "starwisp", "loaded texture");
(*env)->ReleaseStringUTFChars(env, texname, filename);
(*env)->ReleaseByteArrayElements(env,arr,data,JNI_ABORT);
}
// create the engine and output mix objects
void Java_foam_starwisp_Scheme_createEngine(JNIEnv* env, jclass clazz)
{
audio_init();
create_audio_engine();
}
#ifndef APP_H_INCLUDED
#define APP_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#define WINDOW_DEFAULT_WIDTH 640
#define WINDOW_DEFAULT_HEIGHT 480
#define WINDOW_BPP 16
extern void appInit();
extern void initGL();
extern void appDeinit();
extern void appEval(char *code);
extern void appRender(int width, int height);
extern unsigned int appLoadTexture(const char *filename, int width, int height, char* data);
#ifdef __cplusplus
}
#endif
#endif // !APP_H_INCLUDED
#include <jni.h>
#include <sys/time.h>
#include <time.h>
#include <android/log.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
// for native audio
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
//////////////////////////////////////////////77
#include "engine/engine.h"
#include "fluxa/Graph.h"
#include "audio.h"
// audio nonsense
// engine interfaces
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine;
// output mix interfaces
static SLObjectItf outputMixObject = NULL;
// buffer queue player interfaces
static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLEffectSendItf bqPlayerEffectSend;
static SLMuteSoloItf bqPlayerMuteSolo;
static SLVolumeItf bqPlayerVolume;
// recorder interfaces
static SLObjectItf recorderObject = NULL;
static SLRecordItf recorderRecord;
static SLAndroidSimpleBufferQueueItf recorderBufferQueue;
#define RECORDER_FRAMES (160)
static short recorderBufferA[RECORDER_FRAMES];
static short recorderBufferB[RECORDER_FRAMES];
static short processBuffer[RECORDER_FRAMES];
static unsigned recorderSize = 0;
static int current_buffer=-1;
unsigned int noise_size=1000;
unsigned short *noise;
unsigned int size;
Sample *out_left;
Sample *out_right;
Graph *graph;
void audio_init()
{
WaveTable::WriteWaves();
unsigned int s=RECORDER_FRAMES;
out_left=new Sample(s);
out_right=new Sample(s);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "inner init");
size=s;
graph=engine::get()->get_audio_graph();
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "graph is %d", (int)graph);
}
void audio_process(short *data)
{
out_left->Zero();
out_right->Zero();
graph->Process(size/2,*out_left,*out_right);
unsigned int pos=0;
for (unsigned int i=0; i<size; i+=2)
{
data[i]=(short)((*out_left)[pos++]*3276);
}
pos=0;
for (unsigned int i=1; i<size; i+=2)
{
data[i]=(short)((*out_right)[pos++]*3276);
}
}
// this callback handler is called every time a buffer finishes recording
void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
SLresult result;
current_buffer++;
if (current_buffer>1) current_buffer=0;
short *next_buffer=recorderBufferA;
if (current_buffer==1) next_buffer=recorderBufferB;
result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, next_buffer,
RECORDER_FRAMES * sizeof(short));
}
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
short *this_buffer=recorderBufferA;
if (current_buffer==0) this_buffer=recorderBufferB;
memcpy(processBuffer,this_buffer,RECORDER_FRAMES * sizeof(short));
audio_process(processBuffer);
SLresult result; // enqueue another buffer
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, processBuffer, RECORDER_FRAMES*sizeof(short));
}
pthread_t audioThread;
void create_player();
void *AudioInOutThread( void *ptr )
{
SLresult result;
create_player();
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, recorderBufferA, RECORDER_FRAMES*sizeof(short));
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "enqueue saw play %d", result);
// set the player's state to playing
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "started playing %d", result);
}
jboolean setup_recorder()
{
SLresult result;
// configure audio source
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
SLDataSource audioSrc = {&loc_dev, NULL};
// configure audio sink
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
SLDataSink audioSnk = {&loc_bq, &format_pcm};
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID id[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc,
&audioSnk, 1, id, req);
if (SL_RESULT_SUCCESS != result) {
return JNI_FALSE;
}
// realize the audio recorder
result = (*recorderObject)->Realize(recorderObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != result) {
return JNI_FALSE;
}
// get the record interface
result = (*recorderObject)->GetInterface(recorderObject, SL_IID_RECORD, &recorderRecord);
assert(SL_RESULT_SUCCESS == result);
// get the buffer queue interface
result = (*recorderObject)->GetInterface(recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&recorderBufferQueue);
assert(SL_RESULT_SUCCESS == result);
// register callback on the buffer queue
result = (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue, bqRecorderCallback,
NULL);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "recording set up %d", result);
return JNI_TRUE;
}
// create buffer queue audio player
void create_player()
{
SLresult result;
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND,
/*SL_IID_MUTESOLO,*/ SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
/*SL_BOOLEAN_TRUE,*/ SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
3, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the player
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the play interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
// get the buffer queue interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
// register callback on the buffer queue
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
assert(SL_RESULT_SUCCESS == result);
// get the effect send interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND,
&bqPlayerEffectSend);
assert(SL_RESULT_SUCCESS == result);
#if 0 // mute/solo is not supported for sources that are known to be mono, as this is
// get the mute/solo interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
#endif
// get the volume interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
// set the player's state to playing
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "player setup %d", result);
}
void create_audio_engine()
{
SLresult result;
// create engine
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "initEngine");
SLEngineOption EngineOption[] = {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE};
result = slCreateEngine( &engineObject, 1, EngineOption, 0, NULL, NULL);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "create engine result %d", result);
assert(SL_RESULT_SUCCESS == result);
// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the engine interface, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "get engine result %d", result);
// create output mix, with environmental reverb specified as a non-required interface
const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
const SLboolean req[1] = {SL_BOOLEAN_FALSE};
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the output mix
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
result = pthread_create( &audioThread, NULL, AudioInOutThread, NULL);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "created audio playback thread %d", result);
setup_recorder();
// the buffer is not valid for playback yet
recorderSize = 0;
// enqueue an empty buffer to be filled by the recorder
// (for streaming recording, we would enqueue at least 2 empty buffers to start things off)
result = (*recorderBufferQueue)->Enqueue(recorderBufferQueue, recorderBufferA,
RECORDER_FRAMES * sizeof(short));
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "enqueue record A %d", result);
// start recording
result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING);
assert(SL_RESULT_SUCCESS == result);
__android_log_print(ANDROID_LOG_INFO, "NativeAudio", "started recording %d", result);
}
// Copyright (C) 2013 Dave Griffiths
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "db.h"
#include <stdio.h>
db::db(const char *fn) :
m_running(1)
{
int rc = sqlite3_open(fn, &m_db);
if(rc)
{
m_running=0;
}
}
db::~db()
{
}
sqlite3_stmt *db::prepare(const char *sql)
{
sqlite3_stmt *stmt;
const char *test;
int rc = sqlite3_prepare(m_db, sql, strlen(sql), &stmt, NULL);
if( rc != SQLITE_OK )
{
return NULL;
}
return stmt;
}
void db::bind_text(const char *v, int n, sqlite3_stmt *stmt)
{
sqlite3_bind_text(stmt, n, v, strlen(v), 0);
}
void db::bind_int(int v, int n, sqlite3_stmt *stmt)
{
sqlite3_bind_int(stmt, n, v);
}
void db::bind_float(float v, int n, sqlite3_stmt *stmt)
{
sqlite3_bind_double(stmt, n, (double)v);
}
list *db::run(sqlite3_stmt *stmt)
{
list *data= new list;
bool first=true;
int result=0;
do {
result = sqlite3_step(stmt);
if (result == SQLITE_ROW) { /* can read data */
if (first)
{
// first add the column names
list *row = new list;
for (int i=0; i<sqlite3_column_count(stmt); i++) {
row->add_to_end(new db::value_node(sqlite3_column_name(stmt, i)));
}
data->add_to_end(new db::row_node(row));
first=false;
}
list *row = new list;
for (int i=0; i<sqlite3_column_count(stmt); i++)
{
db::value_node *v=NULL;
switch (sqlite3_column_type(stmt, i)) {
case SQLITE_TEXT: v = new db::value_node((char*)sqlite3_column_text(stmt,i)); break;
case SQLITE_INTEGER: v = new db::value_node(sqlite3_column_int(stmt,i)); break;
case SQLITE_FLOAT: v = new db::value_node((float)sqlite3_column_double(stmt,i)); break;
default: v = new db::value_node("NULL"); break; // probably incorrect
};
row->add_to_end(v);
}
data->add_to_end(new db::row_node(row));
}
} while (result == SQLITE_ROW);
sqlite3_finalize(stmt);
return data;
}
///////////////////////////////////
/*
list *db::exec(const char *sql)
{
if (!m_running) return NULL;
char *err = 0;
list *data = new list;
int rc = sqlite3_exec(m_db, sql, callback, data, &err);
if( rc != SQLITE_OK )
{
snprintf(m_status,4096,"SQL error: %s",err);
//m_running=0;
sqlite3_free(err);
}
else
{
snprintf(m_status,4096,"SQL GOOD.");
}
return data;
}
unsigned int db::insert(const char *sql)
{
if (!m_running) return 0;
char *err = 0;
list *data = new list;
int rc = sqlite3_exec(m_db, sql, callback, data, &err);
if( rc != SQLITE_OK )
{
snprintf(m_status,4096,"SQL error: %s",err);
//m_running=0;
sqlite3_free(err);
return 0;
}
else
{
snprintf(m_status,4096,"SQL GOOD.");
}
return sqlite3_last_insert_rowid(m_db);
}
*/
db.o: core/db.cpp core/db.h sqlite/sqlite3.h core/list.h core/types.h \
core/fixed.h core/list.h
// Copyright (C) 2013 Dave Griffiths
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "sqlite/sqlite3.h"
#include "core/list.h"
#include <string.h>
using namespace std;
class db
{
public:
db(const char *fn);
~db();
sqlite3_stmt *prepare(const char *sql);
void bind_text(const char *v, int n, sqlite3_stmt *stmt);
void bind_int(int v, int n, sqlite3_stmt *stmt);
void bind_float(float v, int n, sqlite3_stmt *stmt);
list *run(sqlite3_stmt *stmt);
int last_rowid() { return sqlite3_last_insert_rowid(m_db); }
class value_node: public list::node
{
public:
value_node(const char *v) { m_type='s'; m_strvalue=strdup(v); }
value_node(int v) { m_type='i'; m_intvalue=v; }
value_node(float v) { m_type='f'; m_floatvalue=v; }
~value_node() { if (m_type==