summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArturs Artamonovs <arturs.artamonovs@protonmail.com>2021-07-15 09:40:35 +0100
committerArturs Artamonovs <arturs.artamonovs@protonmail.com>2021-07-15 09:40:35 +0100
commite2d7791085b71212ac0dc859bdab132e05f76ae7 (patch)
treee324e354e2fc2b6f6b75352fd5752303b1edb8f5
parent845dda7e5d0b8a19473166408ed138f0cb9d04ca (diff)
downloadWasmAudio-e2d7791085b71212ac0dc859bdab132e05f76ae7.tar.gz
WasmAudio-e2d7791085b71212ac0dc859bdab132e05f76ae7.zip
Added fir filter code and functions for buffer conversion
-rw-r--r--Build/Makefile5
-rw-r--r--FIR/firmath.c247
-rw-r--r--FIR/firmath.h43
-rw-r--r--WasmAudio.xcodeproj/project.pbxproj52
-rw-r--r--WasmAudio/main.c389
5 files changed, 729 insertions, 7 deletions
diff --git a/Build/Makefile b/Build/Makefile
index 40d6a2e..6fe2da3 100644
--- a/Build/Makefile
+++ b/Build/Makefile
@@ -5,13 +5,12 @@ LDFLAGS=-lSDL2 -lSDL2_ttf
EM_LDFALGS=-s USE_SDL=2 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s LLD_REPORT_UNDEFINED -s USE_GLFW=3
make:
+ $(CC) -c $(SOURCEDIR)/../FIR/firmath.c -g3
$(CC) -c $(SOURCEDIR)/main.c -g3
emcc:
- $(EMCC) $(SOURCEDIR)/main.c -s WASM=1 -O3 -o index.js $(EM_LDFALGS) -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
+ $(EMCC) $(SOURCEDIR)/main.c ../FIR/firmath.c -s WASM=1 -O3 -o index.js $(EM_LDFALGS) -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
-
-
web:
darkhttpd ./ --port 12345
diff --git a/FIR/firmath.c b/FIR/firmath.c
new file mode 100644
index 0000000..3fdf20b
--- /dev/null
+++ b/FIR/firmath.c
@@ -0,0 +1,247 @@
+//
+// firmath.c
+// FIR_rect_win
+//
+// Created by Jacky Jack on 04/07/2021.
+//
+
+#include "firmath.h"
+
+/*
+void window_func_rect(double *w, int N1) {
+ int j;
+
+ for (j=0;j<N1;j++) {
+ w[j] = 1.0;
+ }
+}
+*/
+
+void fir_init(fir_t *fir, uint32_t taps) {
+ int i;
+ for (i=0;i<taps;i++) {
+ fir->fir_coef[i] = (double)0.0;
+ }
+ fir->num_taps = taps;
+}
+
+
+void firw_init(firw_t *fir_win, uint32_t taps) {
+ int i;
+ for (i=0;i<taps;i++) {
+ fir_win->win_coef[i] = (double)0.0;
+ }
+ fir_win->num_taps = taps;
+}
+
+
+double math_sinx(double x) {
+ if (x>-1.0E-5 && x < 1.0E-5) return (1.0);
+ return sin(x)/x;
+}
+
+void fir_sinc_lp(fir_t *fir, double omega_c) {
+ int i;
+ double arg=0.0;
+ //should set 2fc?!
+ printf("omega_c=%f\n",omega_c);
+ for (i=0;i<fir->num_taps;i++) {
+ arg = (double)i-(double)(fir->num_taps-1)/2.0;
+ fir->fir_coef[i] = omega_c * math_sinx(omega_c*arg*M_PI);
+ }
+}
+
+void fir_sinc_hp(fir_t *fir, double omega_c) {
+ int i;
+ double arg=0.0;
+ int even = fir->num_taps%2 ? 0: 1;
+
+ //should set 2fc?!
+ printf("omega_c=%f\n",omega_c);
+ if (even) {
+ for (i=0;i<fir->num_taps;i++) {
+ arg = (double)i-(double)(fir->num_taps-1)/2.0;
+ if (arg == 0.0) {
+ fir->fir_coef[i] = 0.0;
+ } else {
+ //from IOWA
+ fir->fir_coef[i] = cos(omega_c*arg*M_PI)/M_PI/arg + cos(arg*M_PI);
+ }
+ }
+ } else {
+ for (i=0;i<fir->num_taps;i++) {
+ arg = (double)i-(double)(fir->num_taps-1)/2.0;
+ fir->fir_coef[i] = math_sinx(arg*M_PI)-omega_c * math_sinx(omega_c*arg*M_PI);
+ }
+ }
+}
+
+void fir_sinc_bp(fir_t *fir, double omega_c1, double omega_c2) {
+ int i;
+ double arg=0.0;
+ //should set 2fc?!
+ printf("omega_c1=%f\n",omega_c1);
+ printf("omega_c2=%f\n",omega_c2);
+ for (i=0;i<fir->num_taps;i++) {
+ arg = (double)i-(double)(fir->num_taps-1)/2.0;
+ if (arg==0.0) {
+ fir->fir_coef[i] = 0.0;
+ } else {
+ //fir->fir_coef[i] = math_sinx(arg*M_PI) - omega_c2 * math_sinx(omega_c2*arg*M_PI) - omega_c1 * math_sinx(omega_c1*arg*M_PI);
+ fir->fir_coef[i] = (cos(omega_c1*arg*M_PI) - cos(omega_c2*arg*M_PI))/M_PI/arg;
+ }
+ }
+}
+
+void fir_sinc_bs(fir_t *fir, double omega_c1, double omega_c2) {
+ int i;
+ double arg=0.0;
+ //should set 2fc?!
+ printf("omega_c1=%f\n",omega_c1);
+ printf("omega_c2=%f\n",omega_c2);
+ for (i=0;i<fir->num_taps;i++) {
+ arg = (double)i-(double)(fir->num_taps-1)/2.0;
+ if (arg==0.0) {
+ fir->fir_coef[i] = 0.0;
+ } else {
+ //fir->fir_coef[i] = math_sinx(arg*M_PI) - omega_c2 * math_sinx(omega_c2*arg*M_PI) - omega_c1 * math_sinx(omega_c1*arg*M_PI);
+ fir->fir_coef[i] = math_sinx(arg*M_PI) - omega_c2*math_sinx(omega_c2*arg*M_PI) - omega_c1*math_sinx(omega_c1*arg*M_PI);
+ }
+ }
+}
+
+void fir_convolute(fir_t *fir,firw_t *firw) {
+ int i=0;
+ for (i=0;i<fir->num_taps;i++) {
+ fir->fir_coef[i] = fir->fir_coef[i]*firw->win_coef[i];
+ }
+}
+
+
+void firw_rect(firw_t *fir_win) {
+ int i;
+ int n1 = fir_win->num_taps/2;
+ int even = fir_win->num_taps%2 ? 0: 1;
+
+ if (even) n1+=1;
+
+ for (i=0;i<n1;i++) {
+ fir_win->win_coef[i] = 1.0;
+ }
+
+ for (i=0;i<n1;i++) {
+ fir_win->win_coef[fir_win->num_taps-1-i] = fir_win->win_coef[i];
+ }
+
+}
+
+
+void firw_hamming(firw_t *fir_win) {
+ int i;
+ double dN=0;
+ double arg=0;
+ //double p=0;
+ //double arg=0;
+
+ int n1 = fir_win->num_taps/2;
+ int even = fir_win->num_taps%2 ? 0: 1;
+ if (!even) n1+=1;
+ dN = fir_win->num_taps +1;
+
+ for (i=0;i<n1;i++) {
+ //arg = (double)i-(double)(fir_win->num_taps-1)/2.0;
+ //fir_win->win_coef[i] = 0.54+(1-0.54)*cos(2*M_PI*arg/n1);
+
+ //fir_win->win_coef[i] = 0.54+(1-0.54)*cos(2*M_PI*i/n1);
+ arg = (double)i-(double)(fir_win->num_taps-1)/2.0;
+ fir_win->win_coef[i] = 0.54+0.46*cos(2*M_PI*arg/fir_win->num_taps);
+
+ }
+ //fold
+ for (i=0;i<n1;i++) {
+ //arg = (double)i-(double)(fir_win->num_taps-1)/2.0;
+ //fir_win->win_coef[i] = 0.54+(1-0.54)*cos(2*M_PI*arg/n1);
+
+ fir_win->win_coef[fir_win->num_taps-1-i] = fir_win->win_coef[i];
+ }
+
+}
+
+
+void firw_hanning(firw_t *fir_win) {
+ int i;
+ double dN=0;
+ double arg=0;
+
+ int n1 = fir_win->num_taps/2;
+ int even = fir_win->num_taps%2 ? 0: 1;
+ if (!even) n1+=1;
+ dN = fir_win->num_taps +1;
+
+ for (i=0;i<n1;i++) {
+ arg = (double)i-(double)(fir_win->num_taps-1)/2.0;
+ fir_win->win_coef[i] = 0.5+(1-0.5)*cos(2*M_PI*arg/fir_win->num_taps);
+
+ }
+ //fold
+ for (i=0;i<n1;i++) {
+ fir_win->win_coef[fir_win->num_taps-1-i] = fir_win->win_coef[i];
+ }
+}
+
+void firw_blackman(firw_t *firw) {
+ int i;
+ double dN=0;
+ double arg=0;
+
+ int n1 = firw->num_taps/2;
+ int even = firw->num_taps%2 ? 0: 1;
+ if (!even) n1+=1;
+ dN = firw->num_taps +1;
+
+ for (i=0;i<n1;i++) {
+ arg = (double)i-(double)(firw->num_taps-1)/2.0;
+ /*
+ firw->win_coef[i] = 0.42
+ +0.50*cos(2*M_PI*arg/(firw->num_taps))
+ +0.08*cos(4*M_PI*arg/(firw->num_taps));
+ */
+ firw->win_coef[i] = 0.42
+ +0.50*cos(2*M_PI*arg/(firw->num_taps-1))
+ +0.08*cos(4*M_PI*arg/(firw->num_taps-1));
+
+ }
+ //fold
+ for (i=0;i<n1;i++) {
+ firw->win_coef[firw->num_taps-1-i] = firw->win_coef[i];
+ }
+}
+
+void fir_print_matlab(fir_t *fir) {
+ int i;
+ printf("f=[\n");
+ for (i=0;i<fir->num_taps;i++) {
+ printf("%f\n",fir->fir_coef[i]);
+ }
+ printf("];\n");
+}
+
+void firw_print_matlab(firw_t *firw) {
+ int i;
+ printf("w=[\n");
+ for (i=0;i<firw->num_taps;i++) {
+ printf("%f\n",firw->win_coef[i]);
+ }
+ printf("];\n");
+}
+
+
+void fir_print_c(fir_t *fir) {
+ int i;
+ printf("double f=[\n");
+ for (i=0;i<fir->num_taps;i++) {
+ printf("%f,\n",fir->fir_coef[i]);
+ }
+ printf("];\n");
+}
+
diff --git a/FIR/firmath.h b/FIR/firmath.h
new file mode 100644
index 0000000..3540a98
--- /dev/null
+++ b/FIR/firmath.h
@@ -0,0 +1,43 @@
+//
+// firmath.h
+// FIR_rect_win
+//
+// Created by Jacky Jack on 04/07/2021.
+//
+
+#ifndef firmath_h
+#define firmath_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+typedef struct fir_t {
+ uint32_t num_taps;
+ double *fir_coef;
+} fir_t;
+
+typedef struct firw_t {
+ uint32_t num_taps;
+ double *win_coef;
+} firw_t;
+
+void fir_init(fir_t *fir, uint32_t taps);
+void firw_init(firw_t *fir_win, uint32_t taps);
+
+double math_sinx(double x);
+void fir_sinc_lp(fir_t *fir, double fc);
+void fir_sinc_hp(fir_t *fir, double omega_c);
+void fir_sinc_bp(fir_t *fir, double omega_c1, double omega_c2);
+void fir_sinc_bs(fir_t *fir, double omega_c1, double omega_c2);
+void fir_convolute(fir_t *fir,firw_t *fir_win);
+void firw_rect(firw_t *firw);
+void firw_hamming(firw_t *firw);
+void firw_hanning(firw_t *firw);
+void firw_blackman(firw_t *firw);
+void fir_print_matlab(fir_t *fir);
+void firw_print_matlab(firw_t *firw);
+void fir_print_c(fir_t *fir);
+
+#endif /* firmath_h */
diff --git a/WasmAudio.xcodeproj/project.pbxproj b/WasmAudio.xcodeproj/project.pbxproj
index 53e8a8c..4c87b7c 100644
--- a/WasmAudio.xcodeproj/project.pbxproj
+++ b/WasmAudio.xcodeproj/project.pbxproj
@@ -7,7 +7,10 @@
objects = {
/* Begin PBXBuildFile section */
+ 8D1ACB0726A0278200AAF1EB /* firmath.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D1ACB0626A0278200AAF1EB /* firmath.c */; };
8D6E30352694457C007D7ECF /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D6E30342694457C007D7ECF /* main.c */; };
+ 8D6E303F269445E3007D7ECF /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D6E303E269445E2007D7ECF /* SDL2.framework */; };
+ 8D6E30442694472D007D7ECF /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 8D6E30432694472D007D7ECF /* Makefile */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -23,8 +26,15 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 8D1ACB0526A0278200AAF1EB /* firmath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = firmath.h; sourceTree = "<group>"; };
+ 8D1ACB0626A0278200AAF1EB /* firmath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = firmath.c; sourceTree = "<group>"; };
8D6E30312694457C007D7ECF /* WasmAudio */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WasmAudio; sourceTree = BUILT_PRODUCTS_DIR; };
8D6E30342694457C007D7ECF /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+ 8D6E303C269445C8007D7ECF /* Library */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Library; path = ../../../../../Library; sourceTree = "<group>"; };
+ 8D6E303E269445E2007D7ECF /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../../../../../Library/Frameworks/SDL2.framework; sourceTree = "<group>"; };
+ 8D6E304026944620007D7ECF /* SDL2_ttf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2_ttf.framework; path = ../../../../../Library/Frameworks/SDL2_ttf.framework; sourceTree = "<group>"; };
+ 8D6E30432694472D007D7ECF /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+ 8D6E304526944876007D7ECF /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -32,17 +42,30 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 8D6E303F269445E3007D7ECF /* SDL2.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 8D1ACB0426A0276B00AAF1EB /* FIR */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1ACB0626A0278200AAF1EB /* firmath.c */,
+ 8D1ACB0526A0278200AAF1EB /* firmath.h */,
+ );
+ path = FIR;
+ sourceTree = "<group>";
+ };
8D6E30282694457C007D7ECF = {
isa = PBXGroup;
children = (
+ 8D1ACB0426A0276B00AAF1EB /* FIR */,
+ 8D6E3042269446EE007D7ECF /* Build */,
8D6E30332694457C007D7ECF /* WasmAudio */,
8D6E30322694457C007D7ECF /* Products */,
+ 8D6E303B269445C8007D7ECF /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -62,6 +85,25 @@
path = WasmAudio;
sourceTree = "<group>";
};
+ 8D6E303B269445C8007D7ECF /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 8D6E304026944620007D7ECF /* SDL2_ttf.framework */,
+ 8D6E303E269445E2007D7ECF /* SDL2.framework */,
+ 8D6E303C269445C8007D7ECF /* Library */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 8D6E3042269446EE007D7ECF /* Build */ = {
+ isa = PBXGroup;
+ children = (
+ 8D6E304526944876007D7ECF /* index.html */,
+ 8D6E30432694472D007D7ECF /* Makefile */,
+ );
+ path = Build;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -118,6 +160,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 8D1ACB0726A0278200AAF1EB /* firmath.c in Sources */,
+ 8D6E30442694472D007D7ECF /* Makefile in Sources */,
8D6E30352694457C007D7ECF /* main.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -240,6 +284,10 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LOCAL_LIBRARY_DIR)/Frameworks",
+ );
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@@ -248,6 +296,10 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(LOCAL_LIBRARY_DIR)/Frameworks",
+ );
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
diff --git a/WasmAudio/main.c b/WasmAudio/main.c
index b031629..6f1766b 100644
--- a/WasmAudio/main.c
+++ b/WasmAudio/main.c
@@ -5,16 +5,15 @@
// Created by Jacky Jack on 06/07/2021.
//
-#include <stdio.h>
-#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
-#include <strings.h>
+#include <string.h>
#include <getopt.h>
#include <signal.h>
#include <fcntl.h>
#include <pthread.h>
+#include <unistd.h>
@@ -22,9 +21,11 @@
#include <emscripten/emscripten.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
+#include <SDL/SDL_audio.h>
#include <GLES2/gl2.h>
#else
#include <SDL2/SDL.h>
+ #include <SDL2/SDL_audio.h>
#ifdef __APPLE__
#include <SDL2_ttf/SDL_ttf.h>
#else
@@ -34,12 +35,392 @@
//#include <GLES2/gl2.h>
#endif
+#define SCREEN_WIDTH 320
+#define SCREEN_WIDTH2 (SCREEN_WIDTH/2)
+#define SCREEN_HEIGHT 320
+#define SCREEN_HEIGHT2 (SCREEN_HEIGHT/2)
+
+#define BUFSIZE 1536000
+
+//Maximum recording time plus padding
+#define RECORDING_BUFFER_SECONDS (2)
+//Maximum recording time
+#define MAX_RECORDING_SECONDS (RECORDING_BUFFER_SECONDS+2)
+
+int first_run=1;
+static int quit=0;
+static SDL_Window *window = NULL;
+static SDL_Renderer *renderer = NULL;
+//Audio device IDs
+static SDL_AudioDeviceID recordingDeviceId = 0;
+static SDL_AudioDeviceID playbackDeviceId = 0;
+int audio_rec_buffer_size=-1;
+int audio_rec_buffer_max_size=-1;
+//int audio_play_buffer_size=-1;
+//int audio_play_buffer_max_size=-1;
+static uint8_t audio_rec_buffer_[BUFSIZE];
+static double process_buf[BUFSIZE/4];
+uint8_t *audio_rec_buffer=NULL;
+int audio_buf_position=0;
+//uint8_t *audio_play_buffer=NULL;
+int current_state=0;
+
+
+void audio_recording_callback(void *data, uint8_t *insamples, int len)
+{
+ //printf("record len=%d\n",len);
+ if (audio_buf_position<audio_rec_buffer_size) {
+ memcpy( audio_rec_buffer+audio_buf_position, insamples, len);
+ audio_buf_position += len;
+ }
+ //memcpy(insamples, audio_rec_buffer+audio_buf_position, len);
+
+ printf("rec_pos=%d\n",audio_buf_position);
+}
+
+void audio_playback_callback(void *data, uint8_t *outsamples, int len) {
+ //printf("playback len=%d\n",len);
+ //memcpy( audio_rec_buffer,outsamples, len);
+ if (audio_buf_position<audio_rec_buffer_size) {
+ memcpy( outsamples, audio_rec_buffer+audio_buf_position,len);
+ audio_buf_position += len;
+ }
+
+}
+//The various recording actions we can take
+enum RecordingState
+{
+ SELECTING_DEVICE,
+ STOPPED,
+ RECORDING,
+ RECORDED,
+ PLAYBACK,
+ ERROR
+};
+void convert_double_to_f32() {
+ int i;
+ for (i=0;i<audio_rec_buffer_size;i+=4) {
+ float *f_ = (float *)&audio_rec_buffer[i];
+ float f = *f_;
+ process_buf[i/4] = (double)f;
+ }
+}
+
+void convert_f32_to_double() {
+ int i=0;
+ for (i=0;i<audio_rec_buffer_size;i+=4) {
+ double d = process_buf[i/4];
+ float f = (float)d;
+ float *f_ = (float *)audio_rec_buffer;
+ f_[i/4] = (double)f;
+ }
+}
+
+
+uint32_t tick_start, tick_end,tick_1sec;
+
+#if __EMSCRIPTEN__
+void main_tick() {
+#else
+int main_tick() {
+#endif
+ int i,j;
+ int update_fractal=0;
+ uint64_t perf_start, perf_end;
+
+ perf_start = SDL_GetPerformanceCounter();
+ tick_start = SDL_GetTicks();
+
+ SDL_Event event;
+ SDL_StartTextInput();
+ while (SDL_PollEvent(&event) != 0)
+ {
+
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ {
+ quit = 1;
+ break;
+ }
+ case SDL_KEYDOWN:
+ {
+ switch (event.key.keysym.sym)
+ {
+
+ case 21:
+ case SDLK_r:
+ //record if stopped
+ if ((current_state == STOPPED) || (current_state == RECORDED)) {
+ audio_buf_position = 0;
+ SDL_PauseAudioDevice(recordingDeviceId, SDL_FALSE);
+ current_state = RECORDING;
+ printf("State: RECORDING\n");
+ }
+ break;
+ case 22:
+ case SDLK_s:
+ //play if recorded
+ if (current_state == RECORDED) {
+ audio_buf_position = 0;
+ SDL_PauseAudioDevice( playbackDeviceId, SDL_FALSE );
+ current_state = PLAYBACK;
+ printf("State: PLAYBACK\n");
+ } /*else if (current_state == PLAYBACK) {
+ current_state = STOPPED;
+ } else if (current_state == STOPPED) {
+ current_state = PLAYBACK;
+ }*/
+ break;
+ case 20:
+ case SDLK_q:
+ //process recorderd buffer with low pass filter
+ if (current_state == RECORDED) {
+ convert_f32_to_double();
+ convert_double_to_f32();
+ }
+ break;
+ default:
+ printf("Unknown key %d\n",event.key.keysym.sym);
+ update_fractal = 1;
+ }
+ break;
+ }
+ }
+ //printf("Poll event\n");
+
+ }
+#if __EMSCRIPTEN__
+ if (current_state == RECORDING) {
+ SDL_LockAudioDevice( recordingDeviceId );
+ printf("recording=%d\n",audio_buf_position);
+ if( audio_buf_position > audio_rec_buffer_size )
+ {
+ //Stop recording audio
+ SDL_PauseAudioDevice( recordingDeviceId, SDL_TRUE );
+ current_state = RECORDED;
+ printf("State: RECORDED\n");
+ }
+
+ SDL_UnlockAudioDevice( recordingDeviceId );
+ } else if (current_state == PLAYBACK) {
+ SDL_LockAudioDevice( playbackDeviceId );
+ //Finished playback
+ if( audio_buf_position > audio_rec_buffer_size )
+ {
+ //Stop playing audio
+ SDL_PauseAudioDevice( playbackDeviceId, SDL_TRUE );
+ current_state = RECORDED;
+ printf("State: RECORDED\n");
+ }
+ //Unlock callback
+ SDL_UnlockAudioDevice( playbackDeviceId );
+ }
+#endif
+
+
+ //check for first ever run
+ if (first_run == 1)
+ {
+ first_run = 0;
+ update_fractal = 1;
+ }
+
+ if (update_fractal == 1)
+ {
+
+ }
+
+ #ifndef __EMSCRIPTEN__
+ if (update_fractal == 1)
+ #endif
+ {
+ SDL_GL_SwapWindow( window );
+ }
+ update_fractal=0;
+
+ tick_end = SDL_GetTicks();
+ if ((tick_end-tick_1sec)>1000) {
+ //perf_end = SDL_GetPerformanceCounter()-perf_start;
+ //tick_end = SDL_GetTicks()-tick_start;
+ //printf("FPS:%f\n",(1.0f/perf_end));
+ printf("FPS:%f\n",1.0f/((tick_end-tick_start)/1000.0f));
+ tick_1sec = tick_end;
+ }
+
+
+#if !__EMSCRIPTEN__
+ return 0;
+#endif
+}
+
+
+void main_loop()
+{
+ int i,count;
+ tick_1sec = SDL_GetTicks();
+#if __EMSCRIPTEN__
+ emscripten_set_main_loop(main_tick, 25, 1);
+#else
+ while (0 == quit)
+ {
+ main_tick();
+#if !__EMSCRIPTEN__
+ if (current_state == RECORDING) {
+ SDL_LockAudioDevice( recordingDeviceId );
+ printf("recording=%d\n",audio_buf_position);
+ if( audio_buf_position > audio_rec_buffer_size )
+ {
+ //Stop recording audio
+ SDL_PauseAudioDevice( recordingDeviceId, SDL_TRUE );
+ current_state = RECORDED;
+ printf("State: RECORDED\n");
+ }
+
+ SDL_UnlockAudioDevice( recordingDeviceId );
+ } else if (current_state == PLAYBACK) {
+ SDL_LockAudioDevice( playbackDeviceId );
+ //Finished playback
+ if( audio_buf_position > audio_rec_buffer_size )
+ {
+ //Stop playing audio
+ SDL_PauseAudioDevice( playbackDeviceId, SDL_TRUE );
+ current_state = RECORDED;
+ printf("State: RECORDED\n");
+ }
+ //Unlock callback
+ SDL_UnlockAudioDevice( playbackDeviceId );
+ }
+#endif
+ }
+#endif
+}
int main(int argc, const char * argv[]) {
+ int i,count;
// insert code here...
- printf("Hello, World!\n");
+ printf("Hello, World2!\n");
+ //if ( SDL_Init(SDL_INIT_EVERYTHING) < 0 )
+ if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
+ {
+ fprintf(stderr, "EXIT:Unable to init SDL: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+
+
+ atexit(SDL_Quit);
+
+ printf("Prepare SDL2 window\n");
+ SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
+ SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
+ window = SDL_CreateWindow("KOH", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
+ SDL_SetRenderDrawColor(renderer, 0xff, 0xaa, 0xaa, 0xaa);
+ SDL_GLContext gl_context = SDL_GL_CreateContext(window);
+ SDL_GL_SetSwapInterval( 0 );
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+
+ count = SDL_GetNumAudioDevices(0);
+ printf("Playback devices %d\n",count);
+ for (i=0;i<count;i++) {
+ printf("Playback audio device %d: %s\n", i, SDL_GetAudioDeviceName(i, 0));
+ }
+ count = SDL_GetNumAudioDevices(1);
+ printf("Recording devices %d\n",count);
+ for (i=0;i<count;i++) {
+ printf("Recording audio device %d: %s\n", i, SDL_GetAudioDeviceName(i, 1));
+ }
+
+ //https://github.com/emscripten-core/emscripten/issues/3477
+ //try whatever possible
+ SDL_AudioSpec audio_rec_want, audio_rec_have;
+ SDL_memset(&audio_rec_want, 0, sizeof(audio_rec_want)); /* or SDL_zero(want) */
+ audio_rec_want.freq = 48000;
+ audio_rec_want.format = AUDIO_F32;
+ audio_rec_want.channels = 2;
+ audio_rec_want.samples = 4096;
+ audio_rec_want.callback = audio_recording_callback;
+ recordingDeviceId = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(1, SDL_TRUE ), SDL_TRUE, &audio_rec_want, &audio_rec_have, SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
+
+ if (audio_rec_want.freq != audio_rec_have.freq) {
+ printf("Freq changed %d -> %d\n",audio_rec_want.freq,audio_rec_have.freq);
+ }
+
+ if (audio_rec_want.format != audio_rec_have.format) {
+ printf("Format changed %d -> %d\n",audio_rec_want.format, audio_rec_have.format);
+ }
+
+ if (recordingDeviceId == 0) {
+ printf("Failed to open recording device\n");
+ } else {
+ int byte_per_sample = audio_rec_have.channels * ( SDL_AUDIO_BITSIZE( audio_rec_have.format )/8);
+ int byte_per_second = audio_rec_have.freq * byte_per_sample;
+ printf("bytes per second %d\n",byte_per_second);
+ audio_rec_buffer_size = byte_per_second*RECORDING_BUFFER_SECONDS;
+ audio_rec_buffer_max_size = byte_per_second*MAX_RECORDING_SECONDS;
+ //audio_rec_buffer = malloc(audio_rec_buffer_max_size);
+ audio_rec_buffer = &audio_rec_buffer_[0];
+ printf("buffsize_max=%d\n",audio_rec_buffer_max_size);
+ printf("buffsize=%d\n",audio_rec_buffer_size);
+ memset(audio_rec_buffer,0,audio_rec_buffer_max_size);
+ }
+
+ SDL_AudioSpec audio_play_want, audio_play_have;
+ audio_play_want.freq = 48000;
+ audio_play_want.format = AUDIO_F32;
+ audio_play_want.channels = 2;
+ audio_play_want.samples = 4096;
+ audio_play_want.callback = audio_playback_callback;
+ playbackDeviceId = SDL_OpenAudioDevice(NULL, SDL_FALSE, &audio_play_want, &audio_play_have, SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
+
+ if (audio_play_want.freq != audio_play_have.freq) {
+ printf("Freq changed %d -> %d\n",audio_rec_want.freq,audio_rec_have.freq);
+ }
+
+ if (audio_play_want.format != audio_play_have.format) {
+ printf("Format changed %d -> %d\n",audio_play_want.format, audio_play_have.format);
+ }
+ current_state = STOPPED;
+ printf("State: STOPED\n");
+
+
+
+
+
+ //SDL_PauseAudioDevice(recordingDeviceId,0);
+ //!SDL_LockAudioDevice(recordingDeviceId);
+ //SDL_PauseAudioDevice(recordingDeviceId, 0);
+ //SDL_PauseAudio(0);
+ //SDL_Delay(4000);
+ //!SDL_UnlockAudioDevice(recordingDeviceId);
+ //!SDL_CloseAudio();
+ //SDL_CloseAudioDevice(recordingDeviceId);
+ /*
+ if (SDL_OpenAudio(&audio_want, &audio_have) < 0) {
+ SDL_Log("Failed to open audio: %s", SDL_GetError());
+ } else {
+ if (audio_have.format != audio_want.format) {
+ SDL_Log("We didn't get Float32 audio format.");
+ }
+ SDL_PauseAudio(0);
+ SDL_Delay(5000);
+ SDL_CloseAudio();
+ }
+ */
+
+ main_loop();
+
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+ SDL_CloseAudio();//?
+ SDL_VideoQuit();//?
+ SDL_Quit();
+
return 0;
}