int main(void) { struct winsize w; static pa_simple *server; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); //get info on size of screen if(w.ws_col < 5 | w.ws_row < 5) { puts("Fix your terminal m9."); exit(1); } float read_buffer[N]; //buffer into which data will be read double end_buffer[N]; //buffer used as input to fftw fftw_complex out[N]; //buffer for output from fftw #ifdef SMOOTHING unsigned int avg[SMOOTHING][w.ws_col]; #endif char current = 0; unsigned int col; long unsigned int i; #ifdef SMOOTHING i = SMOOTHING; while(i--) memset(avg[i], 0, sizeof(unsigned int) * w.ws_col); #endif server = pulseaudio_begin(); setup_screen(); printf("\e[1;1HAttempting search for most efficient DFT algorithm... FFTW_PATIENT"); fflush(stdout); fftw_plan p = fftw_plan_dft_r2c_1d(N, end_buffer, out, FFTW_PATIENT); while(run) { pulseaudio_read(server, read_buffer, N); for(i = 0; i < N; i++) { end_buffer[i] = (read_buffer[i] * (0.5f * (1 - cos(2 * PI * i / (N - 1))))) * INPUT_AMPLIFY; //apply hann window } fftw_execute(p); printf("\e[f"); #ifdef LOG unsigned int last = 0; #endif for(i = 1; i < w.ws_col + 1; i++) { double freq_logvalue; #ifdef LOG unsigned long int pos = i * i * ((N - TOP_FREQ_SUB) / 2) / (w.ws_col*w.ws_col); if(pos<=last) pos = last + 1; if(pos >= N/2) pos = N/2 - 1; last = (unsigned int) pos; freq_logvalue = log10(cabs(out[pos]) / (N / 2)) * AMPLIFY; //normalize #else freq_logvalue = log10(cabs(out[i * ((N - TOP_FREQ_SUB) / 2) / w.ws_col]) / (N / 2)) * AMPLIFY; #endif freq_logvalue = 1 - (freq_logvalue > -CUTOFF ? freq_logvalue : -CUTOFF) / -CUTOFF; //cut out at -80 col = (unsigned int) ((freq_logvalue > 1 ? 1 : freq_logvalue) * w.ws_row); #ifdef SMOOTHING avg[current][i - 1] = col; } current++; if(current == SMOOTHING) current = 0; for(i = 1; i < w.ws_col + 1; i++) { //col = (avg[0][i - 1] + avg[1][i - 1]) / 2; unsigned char sm = SMOOTHING; col = 0; while(sm--) { col += avg[sm][i - 1]; } col /= SMOOTHING; #endif puts("\e[1;1H"); if(col > (unsigned int) (0.75 * w.ws_row)) puts("\e[31m"); else if(col > (unsigned int) (0.55 * w.ws_row)) puts("\e[33m"); else puts("\e[32m"); prnt('|', col, (unsigned int) i, w.ws_row); prnt(' ', w.ws_row - col, (unsigned int) i, w.ws_row - col); } fflush(stdout); //gotta go faster than that TODO: add some timing functions to cap framerate } clean_screen(); pulseaudio_end(server); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int err; done = 0; snd_pcm_t *handle; FILE *sound_in_fd = NULL; FILE *sound_out_fd = NULL; int channels; short *buffer = NULL; int buffer_l; int buffer_read; struct serial_state_t *serial = NULL; struct ipc_state_t *ipc = NULL; struct receiver *rx_a = NULL; struct receiver *rx_b = NULL; #ifdef HAVE_PULSEAUDIO pa_simple *pa_dev = NULL; #endif /* command line */ parse_cmdline(argc, argv); /* open syslog, write an initial log message and read configuration */ open_log(logname, 0); hlog(LOG_NOTICE, "Starting up..."); if (read_config()) { hlog(LOG_CRIT, "Initial configuration failed."); exit(1); } /* fork a daemon */ if (fork_a_daemon) { int i = fork(); if (i < 0) { hlog(LOG_CRIT, "Fork to background failed: %s", strerror(errno)); fprintf(stderr, "Fork to background failed: %s\n", strerror(errno)); exit(1); } else if (i == 0) { /* child */ /* write pid file, now that we have our final pid... might fail, which is critical */ hlog(LOG_DEBUG, "Writing pid..."); if (!writepid(pidfile)) exit(1); } else { /* parent, quitting */ hlog(LOG_DEBUG, "Forked daemon process %d, parent quitting", i); exit(0); } } signal(SIGINT, closedown); signal(SIGPIPE, brokenconnection); /* initialize position cache for timed JSON AIS transmission */ if (uplink_config) { hlog(LOG_DEBUG, "Initializing cache..."); if (cache_init()) exit(1); hlog(LOG_DEBUG, "Initializing jsonout..."); if (jsonout_init()) exit(1); } /* initialize serial port for NMEA output */ if (serial_port) serial = serial_init(); /* initialize Unix domain socket for communication with gnuaisgui */ ipc = gnuais_ipc_init(); if(ipc == 0){ hlog(LOG_ERR, "Could not open Unix Domain Socket"); } /* initialize the AIS decoders */ if (sound_channels != SOUND_CHANNELS_MONO) { hlog(LOG_DEBUG, "Initializing demodulator A"); rx_a = init_receiver('A', 2, 0,serial,ipc); hlog(LOG_DEBUG, "Initializing demodulator B"); rx_b = init_receiver('B', 2, 1,serial,ipc); channels = 2; } else { hlog(LOG_DEBUG, "Initializing demodulator A"); rx_a = init_receiver('A', 1, 0,serial,ipc); channels = 1; } #ifdef HAVE_PULSEAUDIO if(sound_device != NULL && ((strcmp("pulse",sound_device) == 0) || (strcmp("pulseaudio",sound_device) == 0))){ if((pa_dev = pulseaudio_initialize()) == NULL){ hlog(LOG_CRIT, "Error opening pulseaudio device"); return -1; } buffer_l = 1024; int extra = buffer_l % 5; buffer_l -= extra; buffer = (short *) hmalloc(buffer_l * sizeof(short) * channels); } else if (sound_device){ #else if (sound_device){ #endif if ((err = snd_pcm_open(&handle, sound_device, SND_PCM_STREAM_CAPTURE, 0)) < 0) { hlog(LOG_CRIT, "Error opening sound device (%s)", sound_device); return -1; } if (input_initialize(handle, &buffer, &buffer_l) < 0) return -1; } else if (sound_in_file) { if ((sound_in_fd = fopen(sound_in_file, "r")) == NULL) { hlog(LOG_CRIT, "Could not open sound file %s: %s", sound_in_file, strerror(errno)); return -1; } hlog(LOG_NOTICE, "Reading audio from file: %s", sound_in_file); buffer_l = 1024; int extra = buffer_l % 5; buffer_l -= extra; buffer = (short *) hmalloc(buffer_l * sizeof(short) * channels); } else { hlog(LOG_CRIT, "Neither sound device or sound file configured."); return -1; } if (sound_out_file) { if ((sound_out_fd = fopen(sound_out_file, "w")) == NULL) { hlog(LOG_CRIT, "Could not open sound output file %s: %s", sound_out_file, strerror(errno)); return -1; } hlog(LOG_NOTICE, "Recording audio to file: %s", sound_out_file); } #ifdef HAVE_MYSQL if (mysql_db) { hlog(LOG_DEBUG, "Saving to MySQL database \"%s\"", mysql_db); if (!(my = myout_init())) return -1; if (mysql_keepsmall) hlog(LOG_DEBUG, "Updating database rows only."); else hlog(LOG_DEBUG, "Inserting data to database."); if (mysql_oldlimit) hlog(LOG_DEBUG, "Deleting data older than %d seconds", mysql_oldlimit); } #endif hlog(LOG_NOTICE, "Started"); while (!done) { if (sound_in_fd) { buffer_read = fread(buffer, channels * sizeof(short), buffer_l, sound_in_fd); if (buffer_read <= 0) done = 1; } #ifdef HAVE_PULSEAUDIO else if (pa_dev){ buffer_read = pulseaudio_read(pa_dev, buffer, buffer_l); } #endif else { buffer_read = input_read(handle, buffer, buffer_l); //printf("read %d\n", buffer_read); } if (buffer_read <= 0) continue; if (sound_out_fd) { fwrite(buffer, channels * sizeof(short), buffer_read, sound_out_fd); } if (sound_channels == SOUND_CHANNELS_MONO) { receiver_run(rx_a, buffer, buffer_read); } if (sound_channels == SOUND_CHANNELS_BOTH || sound_channels == SOUND_CHANNELS_RIGHT) { /* ch a/0/right */ receiver_run(rx_a, buffer, buffer_read); } if (sound_channels == SOUND_CHANNELS_BOTH || sound_channels == SOUND_CHANNELS_LEFT) { /* ch b/1/left */ receiver_run(rx_b, buffer, buffer_read); } } hlog(LOG_NOTICE, "Closing down..."); if (sound_in_fd) { fclose(sound_in_fd); } #ifdef HAVE_PULSEAUDIO else if (pa_dev) { pulseaudio_cleanup(pa_dev); } #endif else { input_cleanup(handle); handle = NULL; } if (sound_out_fd) fclose(sound_out_fd); hfree(buffer); gnuais_ipc_deinit(ipc); if (serial) serial_close(serial); if (uplink_config) jsonout_deinit(); if (cache_positions) cache_deinit(); if (rx_a) { struct demod_state_t *d = rx_a->decoder; hlog(LOG_INFO, "A: Received correctly: %d packets, wrong CRC: %d packets, wrong size: %d packets", d->receivedframes, d->lostframes, d->lostframes2); } if (rx_b) { struct demod_state_t *d = rx_b->decoder; hlog(LOG_INFO, "B: Received correctly: %d packets, wrong CRC: %d packets, wrong size: %d packets", d->receivedframes, d->lostframes, d->lostframes2); } free_receiver(rx_a); free_receiver(rx_b); free_config(); close_log(0); return 0; }