// // main.c // WasmAudio // // Created by Jacky Jack on 06/07/2021. // #include #include #include #include #include #include #include #include #include #if __EMSCRIPTEN__ #include #include #include #include #include #else #include #include #ifdef __APPLE__ #include #else #include #endif //how to use on mac? //#include #endif #include "../FIR/firmath.h" #define SCREEN_WIDTH 320 #define SCREEN_WIDTH2 (SCREEN_WIDTH/2) #define SCREEN_HEIGHT 320 #define SCREEN_HEIGHT2 (SCREEN_HEIGHT/2) #define BUFSIZE 1536000 #define BUFSIZE2 (BUFSIZE/2) #define BUFSIZE4 (BUFSIZE/4) #define BUFSIZE8 (BUFSIZE/8) #define BUFSIZE16 (BUFSIZE/16) //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_buf_position=0; int current_state=0; int audio_rec_buffer_size=-1; int audio_rec_buffer_max_size=-1; static uint8_t audio_rec_buffer_[BUFSIZE]; const int process_buf_size = BUFSIZE4; static double process_buf[process_buf_size+100]; static double process_buf2[process_buf_size+100]; uint8_t *audio_rec_buffer=NULL; FILE *f_1,*f_2; fir_t fir_lp; firw_t firw_lp; void audio_recording_callback(void *data, uint8_t *insamples, int len) { if (audio_buf_position BUFSIZE4) { printf("Buffer overflow convert_double_to_f32"); exit(1); } float f = d; int32_t *i32_ = &f,i32=*i32_; audio_rec_buffer[i+3] = ((int)i32>> 24)&0xff; audio_rec_buffer[i+2] = ((int)i32>> 16)&0xff; audio_rec_buffer[i+1] = ((int)i32>> 8)&0xff; audio_rec_buffer[i+0] = ((int)i32&0xff); } //printf("\n"); } void convert_f32_to_double() { int i=0; for (i=0;i ",process_buf[i]); process_buf[i] = process_buf[i]*1.01; if (process_buf[i] > 1.0) process_buf[i] = 1.0; if (process_buf[i] < -1.0) process_buf[i] = -1.0; //printf("%f\n",process_buf[i]); } } void save_to_matlab(char *name) { int i; FILE *f=NULL; char namebuf[256]; snprintf(namebuf,sizeof(namebuf),"%s.mat",name); f = fopen(namebuf,"w+"); fprintf(f,"# Created by me\n"); fprintf(f,"# name: %s\n",name); fprintf(f,"# type: matrix\n"); fprintf(f,"# rows: 1\n"); int dumpSize=BUFSIZE16; fprintf(f,"# columns: %d\n",dumpSize); #if 1 for (i=0;inum_taps-1], input, ilength*sizeof(double)); for (n=0; nfir_coef; inputp = &input[fir->num_taps - 1 + n]; acc = 0; for (k=0;knum_taps;k++) { acc += (*coeffp++)*(*inputp--); } output[n] = acc; } memmove(&input[0], &input[ilength], (fir->num_taps-1)*sizeof(double)); } uint32_t tick_start, tick_end,tick_1sec; #if __EMSCRIPTEN__ void main_tick() { #else int main_tick() { #endif int i; int update_fractal=0; uint64_t perf_start; 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(); save_to_matlab("B1"); //simple volume raise #if 0 convert_dobule_up(); #endif //fir filter apply #if 1 fir_filter(&fir_lp, process_buf, process_buf_size, process_buf2, process_buf_size); memcpy(process_buf,process_buf2,process_buf_size*sizeof(double)); save_to_matlab("B2"); #endif 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 printf("audio_buf_position=%d\n",audio_buf_position); 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) { printf("FPS:%f\n",1.0f/((tick_end-tick_start)/1000.0f)); tick_1sec = tick_end; } #if !__EMSCRIPTEN__ return 0; #endif } void main_loop() { 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 //printf("audio_buf_position=%d audio_rec_buffer_size=%d\n",audio_buf_position,audio_rec_buffer_size); 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; const int N=200; double h[N],w[N]; int filter_N=60; int filter_FS_hz=48000; int filter_FC_hz=1000; double filter_FC=1.0*filter_FC_hz/filter_FS_hz; fir_lp.num_taps =filter_N; fir_lp.fir_coef = h; firw_lp.num_taps = filter_N; firw_lp.win_coef = w; for (i=0;i %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); } printf("F32 is signed (%d)\n",SDL_AUDIO_ISSIGNED(audio_rec_have.format)); printf("F32 is bigend (%d)\n",SDL_AUDIO_ISBIGENDIAN(audio_rec_have.format)); printf("F32 is bitsize(%d)\n",SDL_AUDIO_BITSIZE(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"); f_1 = fopen("pre.txt","w+"); f_2 = fopen("post.txt","w+"); main_loop(); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_CloseAudio();//? SDL_VideoQuit();//? SDL_Quit(); fclose(f_1); fclose(f_2); return 0; }