int prSFWrite(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, *b; a = g->sp - 1; b = g->sp; SNDFILE *file = (SNDFILE*)slotRawPtr(&slotRawObject(a)->slots[0]); if (!isKindOfSlot(b, class_rawarray)) return errWrongType; switch (slotRawObject(b)->obj_format) { case obj_int16 : sf_write_short(file, (short*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_int32 : sf_write_int(file, (int*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_float : sf_write_float(file, (float*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_double : sf_write_double(file, (double*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; default: error("sample format not supported.\n"); return errFailed; } return errNone; }
static uintptr_t recordThread_(void *recordData_) { recordData_t *recordData = (recordData_t *)recordData_; int retval = 0; const int bufsize = 4096; MYFLT buf[bufsize]; _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); while (recordData->running) { pthread_mutex_lock(&recordData->mutex); pthread_cond_wait(&recordData->condvar, &recordData->mutex); int sampsread; do { sampsread = csoundReadCircularBuffer(NULL, recordData->cbuf, buf, bufsize); #ifdef USE_DOUBLE sf_write_double((SNDFILE *) recordData->sfile, buf, sampsread); #else sf_write_float((SNDFILE *) recordData->sfile, buf, sampsread); #endif } while(sampsread != 0); pthread_mutex_unlock(&recordData->mutex); } return (uintptr_t) ((unsigned int) retval); }
static void wavw_fn(void *vst, size_t n, t_num *samples) { t_wavw *st = (t_wavw *) vst; if (st->is_float) sf_write_float(st->file, (float *) samples, n); else sf_write_double(st->file, (double *) samples, n); }
static void mix_to_mono (SNDFILE * infile, SNDFILE * outfile) { double buffer [1024] ; sf_count_t count ; while ((count = sfx_mix_mono_read_double (infile, buffer, ARRAY_LEN (buffer))) > 0) sf_write_double (outfile, buffer, count) ; return ; } /* mix_to_mono */
static void copy_data (SNDFILE *outfile, SNDFILE *infile, unsigned int len, double normfactor) { unsigned int readcount, k ; readcount = len ; while (readcount == len) { readcount = sf_read_double (infile, data, len) ; for (k = 0 ; k < readcount ; k++) data [k] *= normfactor ; sf_write_double (outfile, data, readcount) ; } ; return ; } /* copy_data */
void test_write_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t items, int line_num) { sf_count_t count ; if ((count = sf_write_double (file, test, items)) != items) { printf ("\n\nLine %d", line_num) ; if (pass > 0) printf (" (pass %d)", pass) ; printf (" : sf_write_double failed with short write (%ld => %ld).\n", SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ; fflush (stdout) ; puts (sf_strerror (file)) ; exit (1) ; } ; return ; } /* test_write_double */
static void deinterleave_double (STATE * state) { int read_len ; int ch, k ; do { read_len = sf_readf_double (state->infile, state->din.d, BUFFER_LEN) ; for (ch = 0 ; ch < state->channels ; ch ++) { for (k = 0 ; k < read_len ; k++) state->dout.d [k] = state->din.d [k * state->channels + ch] ; sf_write_double (state->outfile [ch], state->dout.d, read_len) ; } ; } while (read_len > 0) ; } /* deinterleave_double */
int wavfileout_record(struct nz_block * block, nz_real seconds) { struct state * state = (struct state *) (block->block_state_p); int n_frames = nz_frame_rate * seconds / nz_chunk_size; if (n_frames <= 0) return -1; int i = 0; for (; i < n_frames; i++) { nz_real chunk[nz_chunk_size]; if(NZ_PULL(*block, 0, chunk) == NULL) break; #ifdef NZ_REAL_FLOAT sf_write_float(state->file, chunk, nz_chunk_size); #else sf_write_double(state->file, chunk, nz_chunk_size); #endif } sf_write_sync(state->file); return i; }
void WavOut::write(WavInfo wavInfo, int size, char* buf) throw (QLE) { SF_INFO sfInfo; sfInfo.channels = wavInfo.channels; sfInfo.format = wavInfo.getFormat(); sfInfo.samplerate = wavInfo.rate; SNDFILE *sfFile = sf_open(this->path.toStdString().c_str(), SFM_WRITE, &sfInfo); if( ! sfFile ) throw QLE("failed to open " + this->path + " for writing!"); sf_count_t wasWritten = 0; if(size == sizeof(float)) wasWritten = sf_write_float(sfFile, (float*)buf, wavInfo.length); else if(size == sizeof(double)) wasWritten = sf_write_double(sfFile, (double*)buf, wavInfo.length); sf_close(sfFile); if(wavInfo.length != wasWritten) throw QLE("failed to write " + this->path + "!"); }
static void test_float_peak (char *str, char *filename, int typemajor) { SNDFILE *file ; SF_INFO sfinfo ; int k, frames, count ; printf (" test_float_peak : %s ... ", str) ; sfinfo.samplerate = 44100 ; sfinfo.format = (typemajor | SF_FORMAT_FLOAT) ; sfinfo.channels = 4 ; sfinfo.frames = 0 ; frames = BUFFER_LEN / sfinfo.channels ; /* Create some random data with a peak value of 0.66. */ for (k = 0 ; k < BUFFER_LEN ; k++) data [k] = (rand () % 2000) / 3000.0 ; /* Insert some larger peaks a know locations. */ data [4 * (frames / 8) + 0] = (frames / 8) * 0.01 ; /* First channel */ data [4 * (frames / 6) + 1] = (frames / 6) * 0.01 ; /* Second channel */ data [4 * (frames / 4) + 2] = (frames / 4) * 0.01 ; /* Third channel */ data [4 * (frames / 2) + 3] = (frames / 2) * 0.01 ; /* Fourth channel */ if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ; sf_perror (NULL) ; exit (1) ; } ; /* Write the data in four passed. The data is designed so that peaks will ** be written in the different calls to sf_write_double (). */ for (count = 0 ; count < 4 ; count ++) { if ((k = sf_write_double (file, data + count * BUFFER_LEN / 4, BUFFER_LEN / 4)) != BUFFER_LEN / 4) { printf ("Line %d: sf_write_double # %d failed with short write (%d ->%d)\n", __LINE__, count, BUFFER_LEN / 4, k) ; exit (1) ; } ; } ; sf_close (file) ; if (! (file = sf_open (filename, SFM_READ, &sfinfo))) { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ; sf_perror (NULL) ; exit (1) ; } ; if (sfinfo.format != (typemajor | SF_FORMAT_FLOAT)) { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (typemajor | SF_FORMAT_FLOAT), sfinfo.format) ; exit (1) ; } ; if (sfinfo.frames != frames) { printf ("Line %d: Incorrect number of.frames in file. (%d => %ld)\n", __LINE__, frames, (long) sfinfo.frames) ; exit (1) ; } ; if (sfinfo.channels != 4) { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; exit (1) ; } ; /* Get the log buffer data. */ log_buffer [0] = 0 ; sf_command (file, SFC_GET_LOG_INFO, log_buffer, LOG_BUFFER_SIZE) ; if (strlen (log_buffer) == 0) { printf ("Line %d: Empty log buffer,\n", __LINE__) ; exit (1) ; } ; check_logged_peaks (log_buffer) ; sf_close (file) ; unlink (filename) ; printf ("ok\n") ; } /* test_float_peak */
int main(int argc, char *argv[]) { unsigned int r=0, i=0, j=0; unsigned int block_cnt=0, samples_cnt=0; unsigned int padding=0; float inv_N; float factor=16000/44100; #if DEBUG FILE *fIn, *fOut; #endif SNDFILE *sfIn, *sfOut; SF_INFO infos; infos.format=SF_FORMAT_RAW | SF_FORMAT_PCM_16; infos.channels=1; infos.samplerate=44100; /* Input: real data */ double *data; /* After FFT: complex data */ fftw_complex *fft_result; /* Output: real data */ double *ifft_result; fftw_plan plan_forward, plan_backward; data = (double*)fftw_malloc(sizeof(double)*BLOCK_LEN); fft_result = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*COMPLEX_BLOCK_LEN); ifft_result = (double*)fftw_malloc(sizeof(double)*BLOCK_LEN); plan_forward = fftw_plan_dft_r2c_1d(BLOCK_LEN, data, fft_result, FFTW_ESTIMATE); plan_backward = fftw_plan_dft_c2r_1d(BLOCK_LEN, fft_result, ifft_result, FFTW_ESTIMATE); sfIn = sf_open(IN_FILE, SFM_READ, &infos); if ( sfIn==NULL ) { fprintf(stderr, "%d: %s\n", sf_error(sfIn), sf_strerror(sfIn)); return -1; } sfOut = sf_open(OUT_FILE, SFM_WRITE, &infos); if ( sfOut==NULL ) { fprintf(stderr, "%d: %s\n", sf_error(sfOut), sf_strerror(sfOut)); return -1; } #if DEBUG fIn = fopen("in.txt", "w"); if ( fIn == NULL ) { perror("Error"); return -1; } fOut = fopen("out.txt", "w"); if ( fOut == NULL ) { perror("Error"); return -1; } #endif inv_N = 1./(float)BLOCK_LEN; do { /* Try to read a sample */ r=sf_read_double(sfIn, &(data[i]), 1); /* Sample read */ if (r>0) { /* Iterate Samples counter */ samples_cnt++; /* Iterate samples/block counter */ i++; #if DEBUG fprintf(fIn, "[ %f ]\n", data[i]); #endif } else { /* Still some unprocessed samples */ if (i>0) { padding=BLOCK_LEN-i; printf("Unprocessed samples: %d, zero padding with %d samples\n", i, padding); for(j=0;j<padding;j++) { /* Zero padding */ data[j+i]=0; } } } /* Data block ready or last block */ if ((i==BLOCK_LEN) || ( (i>0) && (r==0) )) { unsigned int k=0; block_cnt++; printf("Block read...\n"); /* FFT */ fftw_execute(plan_forward); for(j=0;j<BLOCK_LEN_OUT/2;j++) { fft_result[j][0]=factor*fft_result[j][0]; fft_result[j][1]=factor*fft_result[j][1]; } fft_result[j][0]=fft_result[BLOCK_LEN/2][0]; fft_result[j][1]=fft_result[BLOCK_LEN/2][1]; k=j++; for(j=k;j<BLOCK_LEN_OUT;j++) { fft_result[j][0]=factor*fft_result[j+BLOCK_LEN-BLOCK_LEN_OUT][0]; fft_result[j][1]=factor*fft_result[j+BLOCK_LEN-BLOCK_LEN_OUT][1]; } /* IFFT */ fftw_execute(plan_backward); /* Normalization */ for(j=0;j<i;j++) { ifft_result[j]=inv_N*ifft_result[j]; #if DEBUG fprintf(fOut, "[ %f ]\n", ifft_result[j]); #endif } /* Write samples */ for(j=0;j<BLOCK_LEN_OUT;j++) { sf_write_double(sfOut, &(ifft_result[j]), 1); } /* Reset block counter */ i=0; } } while(r); printf("Done: samples=%d blocks=%d\n", samples_cnt, block_cnt); #if DEBUG fclose(fIn); fclose(fOut); #endif sf_close(sfIn); sf_close(sfOut); fftw_destroy_plan(plan_forward); fftw_destroy_plan(plan_backward); fftw_free(data); fftw_free(fft_result); fftw_free(ifft_result); return 0; }
sf_count_t WriteWaveFile::WriteDouble(double *ptr, sf_count_t items) { return (sf_write_double(sffile, ptr, items)); }
static void double_norm_test (const char *filename) { SNDFILE *file ; SF_INFO sfinfo ; unsigned int k ; print_test_name ("double_norm_test", filename) ; sfinfo.samplerate = 44100 ; sfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16) ; sfinfo.channels = 1 ; sfinfo.frames = BUFFER_LEN ; /* Create double_data with all values being less than 1.0. */ for (k = 0 ; k < BUFFER_LEN / 2 ; k++) double_data [k] = (k + 5) / (2.0 * BUFFER_LEN) ; for (k = BUFFER_LEN / 2 ; k < BUFFER_LEN ; k++) double_data [k] = (k + 5) ; if (! (file = sf_open (filename, SFM_WRITE, &sfinfo))) { printf ("Line %d: sf_open_write failed with error : ", __LINE__) ; fflush (stdout) ; puts (sf_strerror (NULL)) ; exit (1) ; } ; /* Normailsation is on by default so no need to do anything here. */ /*-sf_command (file, "set-norm-double", "true", 0) ;-*/ if ((k = sf_write_double (file, double_data, BUFFER_LEN / 2)) != BUFFER_LEN / 2) { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; exit (1) ; } ; /* Turn normalisation off. */ sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; if ((k = sf_write_double (file, double_data + BUFFER_LEN / 2, BUFFER_LEN / 2)) != BUFFER_LEN / 2) { printf ("Line %d: sf_write_double failed with short write (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; exit (1) ; } ; sf_close (file) ; if (! (file = sf_open (filename, SFM_READ, &sfinfo))) { printf ("Line %d: sf_open_read failed with error : ", __LINE__) ; fflush (stdout) ; puts (sf_strerror (NULL)) ; exit (1) ; } ; if (sfinfo.format != (SF_FORMAT_RAW | SF_FORMAT_PCM_16)) { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, (SF_FORMAT_RAW | SF_FORMAT_PCM_16), sfinfo.format) ; exit (1) ; } ; if (sfinfo.frames != BUFFER_LEN) { printf ("\n\nLine %d: Incorrect number of.frames in file. (%d => %ld)\n", __LINE__, BUFFER_LEN, SF_COUNT_TO_LONG (sfinfo.frames)) ; exit (1) ; } ; if (sfinfo.channels != 1) { printf ("Line %d: Incorrect number of channels in file.\n", __LINE__) ; exit (1) ; } ; /* Read double_data and check that it is normalised (ie default). */ if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; exit (1) ; } ; for (k = 0 ; k < BUFFER_LEN ; k++) if (double_data [k] >= 1.0) { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ; exit (1) ; } ; /* Seek to start of file, turn normalisation off, read double_data and check again. */ sf_seek (file, 0, SEEK_SET) ; sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; exit (1) ; } ; for (k = 0 ; k < BUFFER_LEN ; k++) if (double_data [k] < 1.0) { printf ("\n\nLine %d: double_data [%d] == %f which is less than 1.0\n", __LINE__, k, double_data [k]) ; exit (1) ; } ; /* Seek to start of file, turn normalisation on, read double_data and do final check. */ sf_seek (file, 0, SEEK_SET) ; sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ; if ((k = sf_read_double (file, double_data, BUFFER_LEN)) != BUFFER_LEN) { printf ("\n\nLine %d: sf_read_double failed with short read (%d ->%d)\n", __LINE__, BUFFER_LEN, k) ; exit (1) ; } ; for (k = 0 ; k < BUFFER_LEN ; k++) if (double_data [k] > 1.0) { printf ("\n\nLine %d: double_data [%d] == %f which is greater than 1.0\n", __LINE__, k, double_data [k]) ; exit (1) ; } ; sf_close (file) ; unlink (filename) ; printf ("ok\n") ; } /* double_norm_test */
int Soundfile::writeFrames(double *inputFrames, int samples) { return sf_write_double(sndfile, inputFrames, samples); }
int main (void) { /* This is a buffer of double precision floating point values ** which will hold our data while we process it. */ static double data [BUFFER_LEN] ; /* A SNDFILE is very much like a FILE in the Standard C library. The ** sf_open function return an SNDFILE* pointer when they sucessfully ** open the specified file. */ SNDFILE *infile, *outfile ; /* A pointer to an SF_INFO stutct is passed to sf_open. ** On read, the library fills this struct with information about the file. ** On write, the struct must be filled in before calling sf_open. */ SF_INFO sfinfo ; int readcount ; char *infilename = "input.wav" ; char *outfilename = "output.wav" ; /* Here's where we open the input file. We pass sf_open the file name and ** a pointer to an SF_INFO struct. ** On successful open, sf_open returns a SNDFILE* pointer which is used ** for all subsequent operations on that file. ** If an error occurs during sf_open, the function returns a NULL pointer. ** ** If you are trying to open a raw headerless file you will need to set the ** format and channels fields of sfinfo before calling sf_open(). For ** instance to open a raw 16 bit stereo PCM file you would need the following ** two lines: ** ** sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16 ; ** sfinfo.channels = 2 ; */ if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) { /* Open failed so print an error message. */ printf ("Not able to open input file %s.\n", infilename) ; /* Print the error message from libsndfile. */ sf_perror (NULL) ; return 1 ; } ; if (sfinfo.channels > MAX_CHANNELS) { printf ("Not able to process more than %d channels\n", MAX_CHANNELS) ; return 1 ; } ; /* Open the output file. */ if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo))) { printf ("Not able to open output file %s.\n", outfilename) ; sf_perror (NULL) ; return 1 ; } ; /* While there are.frames in the input file, read them, process ** them and write them to the output file. */ while ((readcount = sf_read_double (infile, data, BUFFER_LEN))) { process_data (data, readcount, sfinfo.channels) ; sf_write_double (outfile, data, readcount) ; } ; /* Close input and output files. */ sf_close (infile) ; sf_close (outfile) ; return 0 ; } /* main */
static void lossy_comp_test_double (char *str, char *filename, int typemajor, int typeminor, double margin) { SNDFILE *file ; SF_INFO sfinfo ; int k, m, seekpos ; unsigned int datalen ; double *orig, *data ; printf (" lossy_comp_test_double : %s ... ", str) ; datalen = BUFFER_SIZE ; orig = (double*) orig_buffer ; data = (double*) test_buffer ; gen_signal (orig_buffer, datalen) ; sfinfo.samplerate = 11025 ; sfinfo.samples = 123456789 ; /* Ridiculous value. */ sfinfo.channels = 1 ; sfinfo.pcmbitwidth = 16 ; sfinfo.format = (typemajor | typeminor) ; if (! (file = sf_open_write (filename, &sfinfo))) { printf ("sf_open_write failed with error : ") ; sf_perror (NULL) ; exit (1) ; } ; if ((k = sf_write_double (file, orig, datalen, 0)) != datalen) { printf ("sf_write_double failed with double write (%d => %d).\n", datalen, k) ; exit (1) ; } ; sf_close (file) ; memset (data, 0, datalen * sizeof (double)) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; if (! (file = sf_open_read (filename, &sfinfo))) { printf ("sf_open_read failed with error : ") ; sf_perror (NULL) ; exit (1) ; } ; if (sfinfo.format != (typemajor | typeminor)) { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", (typemajor | typeminor), sfinfo.format) ; exit (1) ; } ; if (sfinfo.samples < datalen) { printf ("Too few samples in file. (%d should be a little more than %d)\n", datalen, sfinfo.samples) ; exit (1) ; } ; if (sfinfo.samples > (datalen + datalen/2)) { printf ("Too many samples in file. (%d should be a little more than %d)\n", datalen, sfinfo.samples) ; exit (1) ; } ; if (sfinfo.channels != 1) { printf ("Incorrect number of channels in file.\n") ; exit (1) ; } ; if (sfinfo.pcmbitwidth != 16) { printf ("Incorrect bit width (%d).\n", sfinfo.pcmbitwidth) ; exit (1) ; } ; if ((k = sf_read_double (file, data, datalen, 0)) != datalen) { printf ("double read (%d).\n", k) ; exit (1) ; } ; for (k = 0 ; k < datalen ; k++) if (error_function (data [k], orig [k], margin)) { printf ("Incorrect sample (A #%d : %d should be %d).\n", k, (int) data [k], (int) orig [k]) ; exit (1) ; } ; if ((k = sf_read_double (file, data, datalen, 0)) != sfinfo.samples - datalen) { printf ("Incorrect read length (%d should be %d).\n", sfinfo.samples - datalen, k) ; exit (1) ; } ; for (k = 0 ; k < sfinfo.samples - datalen ; k++) if (abs ((int) data [k]) > decay_response (k)) { printf ("Incorrect sample (B #%d : abs (%d) should be < %d).\n", datalen + k, (int) data [k], decay_response (k)) ; exit (1) ; } ; /* Now test sf_seek function. */ if ((k = sf_seek (file, 0, SEEK_SET)) != 0) { printf ("Seek to start of file failed (%d).\n", k) ; exit (1) ; } ; for (m = 0 ; m < 3 ; m++) { if ((k = sf_read_double (file, data, datalen/7, 0)) != datalen / 7) { printf ("Incorrect read length (%d => %d).\n", datalen / 7, k) ; exit (1) ; } ; for (k = 0 ; k < datalen/7 ; k++) if (error_function (data [k], orig [k + m * (datalen / 7)], margin)) { printf ("Incorrect sample (C #%d : %d => %d).\n", k + m * (datalen / 7), (int) orig [k + m * (datalen / 7)], (int) data [k]) ; for (m = 0 ; m < 10 ; m++) printf ("%d ", (int) data [k]) ; printf ("\n") ; exit (1) ; } ; } ; /* Now test sf_seek function. */ seekpos = BUFFER_SIZE / 10 ; /* Check seek from start of file. */ if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos) { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; exit (1) ; } ; if ((k = sf_read_double (file, data, 1, 0)) != 1) { printf ("sf_read_double (file, data, 1) returned %d.\n", k) ; exit (1) ; } ; if (error_function (data [0], orig [seekpos], margin)) { printf ("sf_seek (SEEK_SET) followed by sf_read_double failed (%d, %d).\n", (int) orig [1], (int) data [0]) ; exit (1) ; } ; seekpos += BUFFER_SIZE / 5 ; k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; sf_read_double (file, data, 1, 0) ; if (error_function (data [0], orig [seekpos], margin) || k != seekpos + 1) { printf ("sf_seek (SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", (int) data [0], (int) orig [seekpos], k, seekpos) ; exit (1) ; } ; seekpos -= 20 ; /* Check seek backward from current position. */ k = sf_seek (file, -20, SEEK_CUR) ; sf_read_double (file, data, 1, 0) ; if (error_function (data [0], orig [seekpos], margin) || k != seekpos + 2) { printf ("sf_seek (SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", (int) data [0], (int) orig [seekpos], k, seekpos) ; exit (1) ; } ; /* Check that read past end of file returns number of items. */ sf_seek (file, (int) datalen, SEEK_SET) ; if ((k = sf_read_double (file, data, datalen, 0)) != sfinfo.samples - datalen) { printf ("Return value from sf_read_double past end of file incorrect (%d).\n", k) ; exit (1) ; } ; /* Check seek backward from end. */ if ((k = sf_seek (file, 5 - (int) sfinfo.samples, SEEK_END)) != 5) { printf ("sf_seek (SEEK_END) returned %d instead of %d.\n", k, 5) ; exit (1) ; } ; sf_read_double (file, data, 1, 0) ; if (error_function (data [0], orig [5], margin)) { printf ("sf_seek (SEEK_END) followed by sf_read_double failed (%d, %d).\n", (int) data [0], (int) orig [5]) ; exit (1) ; } ; sf_close (file) ; printf ("ok\n") ; } /* lossy_comp_test_double */
int embed(char *infile_path, char *outfile_path, char *orig_outfile_path) { //{{{ SF_INFO sfinfo; // struct with info on the samplerate, number of channels, etc SNDFILE *s_infile; SNDFILE *s_outfile; SNDFILE *s_orig_out; fftw_plan *ft_forward; fftw_plan *ft_reverse; double *time_buffer; complex *freq_buffer; void (*embed_to_signal)(complex *, int); int channels; if(wmark->type == FH_EMBED) embed_to_signal = &fh_embed_to_signal; else embed_to_signal = &ss_embed_to_signal; seed_rand(wmark->key_seed); set_rand(wmark->len); // // Open input file and output file // ------------------------------- // The pre-open SF_INFO should have format = 0, everything else will be set in the open call sfinfo.format = 0; // s_infile = input audio file if(!(s_infile = sf_open(infile_path, SFM_READ, &sfinfo))){ fprintf(stderr,"error opening the following file for reading: %s\n", infile_path); return 1; } // s_outfile = watermaked audio file if(!(s_outfile = sf_open(outfile_path, SFM_WRITE, &sfinfo))){ fprintf(stderr,"error opening the following file for writing: %s\n", outfile_path); return 1; } // s_orig_out = watermaked audio file if(!(s_orig_out = sf_open(orig_outfile_path, SFM_WRITE, &sfinfo))){ fprintf(stderr,"error opening the following file for writing: %s\n", orig_outfile_path); return 1; } channels = sfinfo.channels; if(embed_verbose) print_sfile_info(sfinfo); // // Read, process, and write data // ----------------------------- time_buffer = (double *) malloc(sizeof(double) * BUFFER_LEN * channels); freq_buffer = (complex *) fftw_malloc(sizeof(complex) * FREQ_LEN * channels); ft_forward = (fftw_plan *)malloc(sizeof(fftw_plan) * sfinfo.channels); ft_reverse = (fftw_plan *)malloc(sizeof(fftw_plan) * sfinfo.channels); for(int i = 0; i < channels; i++){ ft_forward[i] = fftw_plan_dft_r2c_1d(BUFFER_LEN, time_buffer+i*BUFFER_LEN, freq_buffer+i*FREQ_LEN, FFTW_ESTIMATE); ft_reverse[i] = fftw_plan_dft_c2r_1d(BUFFER_LEN, freq_buffer+i*FREQ_LEN, time_buffer+i*BUFFER_LEN, FFTW_ESTIMATE); } int bytes_read; int counter = 0; while(bytes_read = sf_read_double(s_infile, time_buffer, BUFFER_LEN*channels)){ // embed to orig_out to account for some of the floating point errors sf_write_double(s_orig_out, time_buffer, bytes_read); // only embed in a frame where we read in the full amount for the DFT if(bytes_read == BUFFER_LEN*channels){ // if there are, say, 2 channels a,b, the audio will be stored as // a1, b1, a2, b2, ... // convert it to a1, a2, ... , b1, b2, ... deinterleave_channels(time_buffer, channels); for(int i = 0; i < channels; i++) fftw_execute(ft_forward[i]); // DEBUG print embed read info if(counter == embed_debug){ printf("org: "); print_pow_density(freq_buffer, 10); } embed_to_signal(freq_buffer, FREQ_LEN*channels); // DEBUG print embed read info if(counter == embed_debug){ printf("new: "); print_pow_density(freq_buffer, 10); } for(int i = 0; i < channels; i++) fftw_execute(ft_reverse[i]); // The DFT naturally multiplies every array element by the size of the array, reverse this array_div(BUFFER_LEN, time_buffer, BUFFER_LEN*channels); interleave_channels(time_buffer, channels); } // if(bytes_read == BUFFER_LEN) sf_write_double(s_outfile, time_buffer, bytes_read); //if(counter == embed_debug){ // deinterleave_channels(time_buffer, channels); // for(int i = 0; i < channels; i++) // fftw_execute(ft_forward[i]); // printf("pt: "); print_pow_density(freq_buffer,10); // printf("cpt: "); print_complex_array(freq_buffer,10); // for(int i = 0; i < channels; i++) // fftw_execute(ft_reverse[i]); // interleave_channels(time_buffer, channels); // array_div(BUFFER_LEN, time_buffer, BUFFER_LEN*channels); //} counter++; embed_iteration++; } //while // // free everything // --------------- for(int i = 0; i < channels; i++){ fftw_destroy_plan(ft_forward[i]); fftw_destroy_plan(ft_reverse[i]); } free(ft_forward); free(ft_reverse); free(time_buffer); fftw_free(freq_buffer); free_rand(); sf_close(s_infile); sf_close(s_outfile); sf_close(s_orig_out); } //}}}