diff --git a/CMakeLists.txt b/CMakeLists.txt index 8690a6c..afd43cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}" "${CMAKE_INSTALL_PREFIX}/include") LINK_DIRECTORIES("${CMAKE_INSTALL_PREFIX}/lib") ADD_EXECUTABLE(dsd ${SRCS}) -TARGET_LINK_LIBRARIES(dsd mbe) +TARGET_LINK_LIBRARIES(dsd mbe sndfile) install(TARGETS dsd DESTINATION bin) diff --git a/dsd.h b/dsd.h index 9d4c047..d187d6a 100644 --- a/dsd.h +++ b/dsd.h @@ -36,7 +36,7 @@ #endif #include #include - +#include /* * global variables */ @@ -59,8 +59,14 @@ typedef struct int scoperate; char audio_in_dev[1024]; int audio_in_fd; + SNDFILE *audio_in_file; + SF_INFO *audio_in_file_info; + int audio_in_type; // 0 for device, 1 for file char audio_out_dev[1024]; int audio_out_fd; + SNDFILE *audio_out_file; + SF_INFO *audio_out_file_info; + int audio_out_type; // 0 for device, 1 for file int split; int playoffset; char mbe_out_dir[1024]; @@ -69,8 +75,8 @@ typedef struct float audio_gain; int audio_out; char wav_out_file[1024]; - FILE *wav_out_f; - int wav_out_fd; + SNDFILE *wav_out_f; + //int wav_out_fd; int serial_baud; char serial_dev[1024]; int serial_fd; @@ -108,7 +114,7 @@ typedef struct float *audio_out_temp_buf_p; int audio_out_idx; int audio_out_idx2; - int wav_out_bytes; + //int wav_out_bytes; int center; int jitter; int synctype; diff --git a/dsd_audio.c b/dsd_audio.c index e558dfd..90150c9 100644 --- a/dsd_audio.c +++ b/dsd_audio.c @@ -153,6 +153,34 @@ processAudio (dsd_opts * opts, dsd_state * state) void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state) { + int n; + short aout_buf[160]; + short *aout_buf_p; + +// for(n=0; n<160; n++) +// printf("%d ", ((short*)(state->audio_out_temp_buf))[n]); +// printf("\n"); + + aout_buf_p = aout_buf; + state->audio_out_temp_buf_p = state->audio_out_temp_buf; + + for (n = 0; n < 160; n++) + { + if (*state->audio_out_temp_buf_p > (float) 32767) + { + *state->audio_out_temp_buf_p = (float) 32767; + } + else if (*state->audio_out_temp_buf_p < (float) -32768) + { + *state->audio_out_temp_buf_p = (float) -32768; + } + *aout_buf_p = (short) *state->audio_out_temp_buf_p; + aout_buf_p++; + state->audio_out_temp_buf_p++; + } + + sf_write_short(opts->wav_out_f, aout_buf, 160); + /* int n; short aout_buf[160]; @@ -179,6 +207,7 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state) result = write (opts->wav_out_fd, aout_buf, 320); fflush (opts->wav_out_f); state->wav_out_bytes += 320; + */ } void @@ -207,157 +236,185 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state) void openAudioOutDevice (dsd_opts * opts, int speed) { + // get info of device/file + struct stat stat_buf; + stat(opts->audio_out_dev, &stat_buf); + if(S_ISREG(stat_buf.st_mode)) { // is this a regular file? then process with libsndfile. + opts->audio_out_type = 1; + opts->audio_out_file_info = calloc(1, sizeof(SF_INFO)); + opts->audio_out_file_info->samplerate = 48000; + opts->audio_out_file_info->channels = 1; + opts->audio_out_file_info->format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE; + opts->audio_out_file = sf_open(opts->audio_out_dev, SFM_READ, opts->audio_out_file_info); + if(opts->audio_out_file == NULL) { + printf ("Error, couldn't open file %s\n", opts->audio_in_dev); + } + } + else { // this is a device, use old handling #ifdef SOLARIS - sample_info_t aset, aget; - - opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY); - if (opts->audio_out_fd == -1) - { - printf ("Error, couldn't open %s\n", opts->audio_out_dev); - exit (1); - } - - // get current - ioctl (opts->audio_out_fd, AUDIO_GETINFO, &aset); - - aset.record.sample_rate = speed; - aset.play.sample_rate = speed; - aset.record.channels = 1; - aset.play.channels = 1; - aset.record.precision = 16; - aset.play.precision = 16; - aset.record.encoding = AUDIO_ENCODING_LINEAR; - aset.play.encoding = AUDIO_ENCODING_LINEAR; - - if (ioctl (opts->audio_out_fd, AUDIO_SETINFO, &aset) == -1) - { - printf ("Error setting sample device parameters\n"); - exit (1); - } + sample_info_t aset, aget; + + opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY); + if (opts->audio_out_fd == -1) + { + printf ("Error, couldn't open %s\n", opts->audio_out_dev); + exit (1); + } + + // get current + ioctl (opts->audio_out_fd, AUDIO_GETINFO, &aset); + + aset.record.sample_rate = speed; + aset.play.sample_rate = speed; + aset.record.channels = 1; + aset.play.channels = 1; + aset.record.precision = 16; + aset.play.precision = 16; + aset.record.encoding = AUDIO_ENCODING_LINEAR; + aset.play.encoding = AUDIO_ENCODING_LINEAR; + + if (ioctl (opts->audio_out_fd, AUDIO_SETINFO, &aset) == -1) + { + printf ("Error setting sample device parameters\n"); + exit (1); + } #endif #if defined(BSD) && !defined(__APPLE__) - - int fmt; - - opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY); - if (opts->audio_out_fd == -1) - { - printf ("Error, couldn't open %s\n", opts->audio_out_dev); - opts->audio_out = 0; - } - - fmt = 0; - if (ioctl (opts->audio_out_fd, SNDCTL_DSP_RESET) < 0) - { - printf ("ioctl reset error \n"); - } - fmt = speed; - if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0) - { - printf ("ioctl speed error \n"); - } - fmt = 0; - if (ioctl (opts->audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0) - { - printf ("ioctl stereo error \n"); - } - fmt = AFMT_S16_LE; - if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) - { - printf ("ioctl setfmt error \n"); - } - + + int fmt; + + opts->audio_out_fd = open (opts->audio_out_dev, O_WRONLY); + if (opts->audio_out_fd == -1) + { + printf ("Error, couldn't open %s\n", opts->audio_out_dev); + opts->audio_out = 0; + } + + fmt = 0; + if (ioctl (opts->audio_out_fd, SNDCTL_DSP_RESET) < 0) + { + printf ("ioctl reset error \n"); + } + fmt = speed; + if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SPEED, &fmt) < 0) + { + printf ("ioctl speed error \n"); + } + fmt = 0; + if (ioctl (opts->audio_out_fd, SNDCTL_DSP_STEREO, &fmt) < 0) + { + printf ("ioctl stereo error \n"); + } + fmt = AFMT_S16_LE; + if (ioctl (opts->audio_out_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) + { + printf ("ioctl setfmt error \n"); + } + #endif - + } printf ("Audio Out Device: %s\n", opts->audio_out_dev); } void openAudioInDevice (dsd_opts * opts) { - + // get info of device/file + struct stat stat_buf; + stat(opts->audio_in_dev, &stat_buf); + if(S_ISREG(stat_buf.st_mode)) { // is this a regular file? then process with libsndfile. + opts->audio_in_type = 1; + opts->audio_in_file_info = calloc(1, sizeof(SF_INFO)); + opts->audio_in_file_info->channels = 1; + opts->audio_in_file = sf_open(opts->audio_in_dev, SFM_READ, opts->audio_in_file_info); + if(opts->audio_in_file == NULL) { + printf ("Error, couldn't open file %s\n", opts->audio_in_dev); + } + } + else { // this is a device, use old handling + opts->audio_in_type = 0; #ifdef SOLARIS - sample_info_t aset, aget; - int rgain; - - rgain = 64; - - if (opts->split == 1) - { - opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY); - } - else - { - opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR); - } - if (opts->audio_in_fd == -1) - { - printf ("Error, couldn't open /dev/audio\n"); - } - - // get current - ioctl (opts->audio_in_fd, AUDIO_GETINFO, &aset); - - aset.record.sample_rate = 48000; - aset.play.sample_rate = 48000; - aset.record.channels = 1; - aset.play.channels = 1; - aset.record.precision = 16; - aset.play.precision = 16; - aset.record.encoding = AUDIO_ENCODING_LINEAR; - aset.play.encoding = AUDIO_ENCODING_LINEAR; - aset.record.port = AUDIO_LINE_IN; - aset.record.gain = rgain; - - if (ioctl (opts->audio_in_fd, AUDIO_SETINFO, &aset) == -1) - { - printf ("Error setting sample device parameters\n"); - exit (1); - } + sample_info_t aset, aget; + int rgain; + + rgain = 64; + + if (opts->split == 1) + { + opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY); + } + else + { + opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR); + } + if (opts->audio_in_fd == -1) + { + printf ("Error, couldn't open /dev/audio\n"); + } + + // get current + ioctl (opts->audio_in_fd, AUDIO_GETINFO, &aset); + + aset.record.sample_rate = 48000; + aset.play.sample_rate = 48000; + aset.record.channels = 1; + aset.play.channels = 1; + aset.record.precision = 16; + aset.play.precision = 16; + aset.record.encoding = AUDIO_ENCODING_LINEAR; + aset.play.encoding = AUDIO_ENCODING_LINEAR; + aset.record.port = AUDIO_LINE_IN; + aset.record.gain = rgain; + + if (ioctl (opts->audio_in_fd, AUDIO_SETINFO, &aset) == -1) + { + printf ("Error setting sample device parameters\n"); + exit (1); + } #endif #if defined(BSD) && !defined(__APPLE__) - int fmt; - - if (opts->split == 1) - { - opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY); - } - else - { - opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR); - } - - if (opts->audio_in_fd == -1) - { - printf ("Error, couldn't open %s\n", opts->audio_in_dev); - opts->audio_out = 0; - } - - fmt = 0; - if (ioctl (opts->audio_in_fd, SNDCTL_DSP_RESET) < 0) - { - printf ("ioctl reset error \n"); - } - fmt = 48000; - if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SPEED, &fmt) < 0) - { - printf ("ioctl speed error \n"); - } - fmt = 0; - if (ioctl (opts->audio_in_fd, SNDCTL_DSP_STEREO, &fmt) < 0) - { - printf ("ioctl stereo error \n"); - } - fmt = AFMT_S16_LE; - if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) - { - printf ("ioctl setfmt error \n"); - } + int fmt; + + if (opts->split == 1) + { + opts->audio_in_fd = open (opts->audio_in_dev, O_RDONLY); + } + else + { + opts->audio_in_fd = open (opts->audio_in_dev, O_RDWR); + } + + if (opts->audio_in_fd == -1) + { + printf ("Error, couldn't open %s\n", opts->audio_in_dev); + opts->audio_out = 0; + } + + fmt = 0; + if (ioctl (opts->audio_in_fd, SNDCTL_DSP_RESET) < 0) + { + printf ("ioctl reset error \n"); + } + fmt = 48000; + if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SPEED, &fmt) < 0) + { + printf ("ioctl speed error \n"); + } + fmt = 0; + if (ioctl (opts->audio_in_fd, SNDCTL_DSP_STEREO, &fmt) < 0) + { + printf ("ioctl stereo error \n"); + } + fmt = AFMT_S16_LE; + if (ioctl (opts->audio_in_fd, SNDCTL_DSP_SETFMT, &fmt) < 0) + { + printf ("ioctl setfmt error \n"); + } #endif - + } if (opts->split == 1) { printf ("Audio In Device: %s\n", opts->audio_in_dev); diff --git a/dsd_file.c b/dsd_file.c index 476acb7..25fcbc9 100644 --- a/dsd_file.c +++ b/dsd_file.c @@ -272,75 +272,30 @@ void openWavOutFile (dsd_opts * opts, dsd_state * state) { - opts->wav_out_f = fopen (opts->wav_out_file, "w"); + // opts->wav_out_f = fopen (opts->wav_out_file, "w"); + + SF_INFO info; + info.samplerate = 8000; + info.channels = 1; + info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE; + opts->wav_out_f = sf_open (opts->wav_out_file, SFM_WRITE, &info); + if (opts->wav_out_f == NULL) - { - printf ("Error - could not open wav output file %s\n", opts->wav_out_file); - return; - } - opts->wav_out_fd = fileno (opts->wav_out_f); - state->wav_out_bytes = 0; + { + printf ("Error - could not open wav output file %s\n", opts->wav_out_file); + return; + } - fprintf (opts->wav_out_f, "RIFF"); - // total length - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - fprintf (opts->wav_out_f, "WAVE"); - fprintf (opts->wav_out_f, "fmt "); - - // length of format chunk - fputc (16, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // always 0x1 - fputc (1, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // channels - fputc (1, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // sample rate - fputc (64, opts->wav_out_f); - fputc (31, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // bytes per second - fputc (176, opts->wav_out_f); - fputc (62, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // block align - fputc (2, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // bits/sample - fputc (16, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - // data chunk header - fprintf (opts->wav_out_f, "data"); - - // length of data - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - fputc (0, opts->wav_out_f); - - fflush (opts->wav_out_f); +// state->wav_out_bytes = 0; + } void closeWavOutFile (dsd_opts * opts, dsd_state * state) { + sf_close(opts->wav_out_f); +/* int length; if (opts->wav_out_f != NULL) @@ -350,7 +305,7 @@ closeWavOutFile (dsd_opts * opts, dsd_state * state) fprintf (opts->wav_out_f, "RIFF"); // total length - fputc (((36 + length) & 0xff), opts->wav_out_f); + fputc (((36 + length) & 0xff), opts->≈≈); fputc ((((36 + length) >> 8) & 0xff), opts->wav_out_f); fputc ((((36 + length) >> 16) & 0xff), opts->wav_out_f); fputc ((((36 + length) >> 24) & 0xff), opts->wav_out_f); @@ -403,4 +358,5 @@ closeWavOutFile (dsd_opts * opts, dsd_state * state) fflush (opts->wav_out_f); } + */ } diff --git a/dsd_main.c b/dsd_main.c index 9a12711..866fda5 100644 --- a/dsd_main.c +++ b/dsd_main.c @@ -106,7 +106,7 @@ initOpts (dsd_opts * opts) opts->audio_out = 1; opts->wav_out_file[0] = 0; opts->wav_out_f = NULL; - opts->wav_out_fd = -1; + //opts->wav_out_fd = -1; opts->serial_baud = 115200; sprintf (opts->serial_dev, "/dev/ttyUSB0"); opts->resume = 0; @@ -149,7 +149,7 @@ initState (dsd_state * state) state->audio_out_idx = 0; state->audio_out_idx2 = 0; state->audio_out_temp_buf_p = state->audio_out_temp_buf; - state->wav_out_bytes = 0; + //state->wav_out_bytes = 0; state->center = 0; state->jitter = -1; state->synctype = -1; diff --git a/dsd_mbe.c b/dsd_mbe.c index c8051db..884a218 100644 --- a/dsd_mbe.c +++ b/dsd_mbe.c @@ -38,12 +38,12 @@ playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv) readImbe4400Data (opts, state, imbe_d); mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality); processAudio (opts, state); - if (opts->wav_out_fd != -1) + if (opts->wav_out_f != NULL) { writeSynthesizedVoice (opts, state); } - if (opts->audio_out == 1) + if (opts->audio_out != 1) { playSynthesizedVoice (opts, state); } @@ -53,7 +53,7 @@ playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv) readAmbe2450Data (opts, state, ambe_d); mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality); processAudio (opts, state); - if (opts->wav_out_fd != -1) + if (opts->wav_out_f != NULL) { writeSynthesizedVoice (opts, state); } @@ -114,7 +114,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a } processAudio (opts, state); - if (opts->wav_out_fd != -1) + if (opts->wav_out_f != NULL) { writeSynthesizedVoice (opts, state); } diff --git a/dsd_symbol.c b/dsd_symbol.c index b8fd812..e8d3849 100644 --- a/dsd_symbol.c +++ b/dsd_symbol.c @@ -78,8 +78,16 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync) } state->jitter = -1; } - - result = read (opts->audio_in_fd, &sample, 2); + if(opts->audio_in_type == 0) { + result = read (opts->audio_in_fd, &sample, 2); + } + else { + result = sf_read_short(opts->audio_in_file, &sample, 1); + if(result == 0) { + cleanupAndExit (opts, state); + } + } + // printf("res: %zd\n, offset: %lld", result, sf_seek(opts->audio_in_file, 0, SEEK_CUR)); { #define NZEROS 60 #define GAIN 7.423339364e+00