WavReader::WavReader(const std::string &filePath) { //hasOutput(); SNDFILE *file; SF_INFO info; /* Open the WAV file. */ info.format = 0; file = sf_open(filePath.c_str(), SFM_READ, &info); if (file == NULL) { printf("Failed to open the file.\n"); exit(-1); } sf_count_t frameCount = info.frames; sampleRate = info.samplerate; channelCount = info.channels; // printf("frames: %lld\n", frameCount); // printf("samplerate: %d\n", sampleRate); // printf("channels: %d\n", channelCount); sampleCount = frameCount * channelCount; // printf("num_items: %lld\n", sampleCount); buffer = new double[sampleCount]; sf_read_double(file, buffer, sampleCount); sf_close(file); }
index_t soundfile_read_double(soundfile_t *sf, double *buffer, index_t n_frames) { if (sf->t == sft_libsndfile) { return sf_read_double(sf->p, buffer, n_frames); } else { int buffer_size = 65536; int32_t b[buffer_size*sf->channels]; index_t frames_read = 0; double divisor = 1L << (sf->bits_per_sample - 1); while (1) { int to_read = MIN(buffer_size, n_frames - frames_read); if (to_read <= 0) return frames_read; int n = WavpackUnpackSamples(sf->p, b, to_read); if (n < 0 || (n == 0 && frames_read == 0)) die("WavpackUnpackSamples returned %d", n); if (n == 0) return frames_read; for (index_t f = 0; f < n; f++) { for (int c = 0; c < sf->channels; c++) buffer[frames_read*sf->channels+c] = b[f*sf->channels+c]/divisor; frames_read++; } } } }
int prSFRead(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 : slotRawObject(b)->size = (int)sf_read_short(file, (short*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_int32 : slotRawObject(b)->size = (int)sf_read_int(file, (int*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_float : slotRawObject(b)->size = (int)sf_read_float(file, (float*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; case obj_double : slotRawObject(b)->size = (int)sf_read_double(file, (double*)slotRawInt8Array(b)->b, slotRawObject(b)->size); break; default: error("sample format not supported.\n"); return errFailed; } return errNone; }
void * libsndfile_stream_get(s_stream * stream, void * buffer, int * size, s_params * params) { int itemsread; libsndfile_context *context; int items; int itemssize; int i; short int *intbuffer; context = (libsndfile_context *)s_stream_context_get(stream); if (context != NULL) { /* fixme 20020924 thammer : support other (return) formats * than 16 bit signed. This should be very little work! */ /* * size must be an integer multiple of bytespersample*channels */ if ( (*size) % (2 * context->sfinfo.channels) ) { *size = 0; return NULL; } items = *size / 2; itemssize = items*sizeof(double); if (context->tempbuffersize < itemssize) { if (context->tempbuffer) free(context->tempbuffer); context->tempbuffer = (double *)malloc(itemssize); } intbuffer = (short int*)buffer; itemsread = sf_read_double(context->file, context->tempbuffer, items); for (i=0; i<itemsread; i++) { intbuffer[i] = context->tempbuffer[i] * (double)32767.0; } if (itemsread > 0) { *size = itemsread * 2; return buffer; } /* fixme 20020924 thammer: check params for conversion requests */ } *size = 0; return NULL; }
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 */
bool Signal::loadFromFile(const std::string& filename) { SampleType *value = new SampleType(0.0); clean(); mSoundInfo = new SF_INFO; mSoundInfo->format = 0; mSoundFile = sf_open(filename.data(), SFM_READ, mSoundInfo); if (mSoundFile == 0) return false; while(sf_read_double(mSoundFile, value, 1)) { mSamples.push_back( *value ); } sf_seek(mSoundFile, 0, SEEK_SET); return true; }
void test_read_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t items, int line_num) { sf_count_t count ; if ((count = sf_read_double (file, test, items)) != items) { printf ("\n\nLine %d", line_num) ; if (pass > 0) printf (" (pass %d)", pass) ; printf (" : sf_read_double failed with short read (%ld => %ld).\n", SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ; fflush (stdout) ; puts (sf_strerror (file)) ; exit (1) ; } ; return ; } /* test_read_double */
uint32_t readWav(char *filename, SF_INFO *info, uint16_t **buffer) { SNDFILE *file = sf_open(filename, SFM_READ, info); uint32_t nFrames = info->frames; if (!file) fprintf(stderr, "Unable to read wav file: %s\n", filename); *buffer = malloc(sizeof(uint16_t) * nFrames); double *imm_buffer = malloc(sizeof(double) * nFrames); uint32_t bytesRead = sf_read_double(file, imm_buffer, nFrames); for (uint32_t i = 0; i < bytesRead; ++i) { (*buffer)[i] = (uint8_t) ((1.0 + imm_buffer[i]) * (UCHAR_MAX / 2)); } return bytesRead; }
int psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize) { sf_count_t position ; double temp, *data ; int k, len, readcount, save_state ; int chan ; /* If the file is not seekable, there is nothing we can do. */ if (! psf->sf.seekable) return (psf->error = SFE_NOT_SEEKABLE) ; if (! psf->read_double) return (psf->error = SFE_UNIMPLEMENTED) ; save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ; sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ; memset (peaks, 0, sizeof (double) * psf->sf.channels) ; /* Brute force. Read the whole file and find the biggest sample for each channel. */ position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Get current position in file */ sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ; /* Go to start of file. */ len = ARRAY_LEN (psf->u.dbuf) ; data = psf->u.dbuf ; chan = 0 ; readcount = len ; while (readcount > 0) { readcount = sf_read_double ((SNDFILE*) psf, data, len) ; for (k = 0 ; k < readcount ; k++) { temp = fabs (data [k]) ; peaks [chan] = temp > peaks [chan] ? temp : peaks [chan] ; chan = (chan + 1) % psf->sf.channels ; } ; } ; sf_seek ((SNDFILE*) psf, position, SEEK_SET) ; /* Return to original position. */ sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ; return 0 ; } /* psf_calc_max_all_channels */
double psf_calc_signal_max (SF_PRIVATE *psf, int normalize) { sf_count_t position ; double max_val, temp, *data ; int k, len, readcount, save_state ; /* If the file is not seekable, there is nothing we can do. */ if (! psf->sf.seekable) { psf->error = SFE_NOT_SEEKABLE ; return 0.0 ; } ; if (! psf->read_double) { psf->error = SFE_UNIMPLEMENTED ; return 0.0 ; } ; save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ; sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ; /* Brute force. Read the whole file and find the biggest sample. */ /* Get current position in file */ position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Go to start of file. */ sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ; data = psf->u.dbuf ; len = ARRAY_LEN (psf->u.dbuf) ; for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */) { readcount = sf_read_double ((SNDFILE*) psf, data, len) ; for (k = 0 ; k < readcount ; k++) { temp = fabs (data [k]) ; max_val = temp > max_val ? temp : max_val ; } ; } ; /* Return to SNDFILE to original state. */ sf_seek ((SNDFILE*) psf, position, SEEK_SET) ; sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ; return max_val ; } /* psf_calc_signal_max */
static double get_signal_max (SNDFILE *file) { double max, temp ; int readcount, k, save_state ; save_state = sf_command (file, SFC_GET_NORM_DOUBLE, NULL, 0) ; sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; max = 0.0 ; while ((readcount = sf_read_double (file, data, BUFFER_LEN))) { for (k = 0 ; k < readcount ; k++) { temp = fabs (data [k]) ; if (temp > max) max = temp ; } ; } ; sf_command (file, SFC_SET_NORM_DOUBLE, NULL, save_state) ; return max ; } /* get_signal_max */
void convert_mono_to_stereo(char* filepath, char* new_file_name){ SNDFILE *infile, *outfile; SF_INFO sfinfo, sfOutInfo; sf_count_t readCount; double *input_buffer, *output_buffer; sfinfo.format=0; if (! (infile = sf_open(filepath, SFM_READ, &sfinfo))) { printf ("Not able to open input file %s.\n", filepath) ; sf_perror(NULL); } input_buffer = malloc(sfinfo.frames * sizeof(double)); output_buffer = malloc(sfinfo.frames * sizeof(double)); readCount = sf_read_double(infile, input_buffer, sfinfo.frames); for(int i = 0; i < sfinfo.frames * 2; i+=2){ output_buffer[i] = input_buffer[i/2]; } for(int i = 0; i < sfinfo.frames *2; i+=2){ output_buffer[i] = input_buffer[(int)(i/2) - 1]; } sfOutInfo.frames = sfinfo.frames * 2; sfOutInfo.samplerate = sfinfo.samplerate; sfOutInfo.channels = sfinfo.channels * 2; sfOutInfo.format = SF_FORMAT_AIFF | SF_FORMAT_PCM_16; if (! (outfile = sf_open(filepath, SFM_WRITE, &sfOutInfo))) { printf ("Not able to open input file %s.\n", filepath) ; sf_perror(NULL); } sf_close(infile); sf_close(outfile); free(input_buffer); free(output_buffer); }
static void interleave_double (STATE * state) { int max_read_len, read_len ; int ch, k ; do { max_read_len = 0 ; for (ch = 0 ; ch < state->channels ; ch ++) { read_len = sf_read_double (state->infile [ch], state->din.d, BUFFER_LEN) ; if (read_len < BUFFER_LEN) memset (state->din.d + read_len, 0, sizeof (state->din.d [0]) * (BUFFER_LEN - read_len)) ; for (k = 0 ; k < BUFFER_LEN ; k++) state->dout.d [k * state->channels + ch] = state->din.d [k] ; max_read_len = MAX (max_read_len, read_len) ; } ; sf_writef_double (state->outfile, state->dout.d, max_read_len) ; } while (max_read_len > 0) ; } /* interleave_double */
int Soundfile::readFrames(double *outputFrames, int samples) { return sf_read_double(sndfile, outputFrames, 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 main (int argc, char *argv[]) { char *filename, *outname; if(argc != 3){ printf("Syntax: draw_waveform in.wav out.png\n"); return 0; }else{ filename = argv[1]; outname = argv[2]; } cairo_surface_t *surface; cairo_t *cr; int inset = 15; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); cr = cairo_create (surface); /* Examples are in 1.0 x 1.0 coordinate space */ int color_1 = 0x1a2421; /* Dark Jungle Green*/ int color_2 = 0x8cbed6; /* Dark Sky Blue*/ int color_3 = 0xffbcd9; /* Bubblegum Pink*/ /* Drawing code goes here */ /* Font Configuration */ cairo_font_extents_t fe; cairo_text_extents_t te; cairo_set_font_size(cr, 10); cairo_select_font_face (cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_font_extents (cr, &fe); cairo_set_line_width (cr, 1); set_color(cr, color_1); cairo_paint(cr); static double data [BUFFER_LEN] ; SNDFILE *infile; SF_INFO sfinfo ; if (! (infile = sf_open (filename, SFM_READ, &sfinfo))) { printf ("Not able to open input file %s.\n", filename) ; puts (sf_strerror (NULL)) ; return 1 ; } ; if (sfinfo.channels != 1) { printf ("Not able to process more than %d channels\n", MAX_CHANNELS) ; return 1 ; } ; sf_read_double (infile, data, BUFFER_LEN); float zero = (HEIGHT/2) - 0.5; float amp = (HEIGHT - 2 * inset) * -0.5 * 0.8; int skip = 2048.0 / (WIDTH - 2 * inset); int i; set_color (cr, color_3); cairo_move_to (cr, inset, zero); //cairo_line_to (cr, WIDTH - inset, HEIGHT - inset - 2); for(i = 0; i < (WIDTH - 2 * inset); i++) cairo_line_to (cr, inset + i, zero + data[i * skip] * amp); cairo_stroke (cr); /* set frame */ set_color(cr, color_2); cairo_rectangle (cr, inset - 0.5, inset - 0.5, WIDTH - 2 * inset, HEIGHT - 2 * inset); cairo_stroke (cr); /*write text */ cairo_move_to (cr, inset, HEIGHT - 5); cairo_show_text (cr, filename); cairo_stroke (cr); /* Write output and clean up */ sf_close (infile) ; cairo_surface_write_to_png (surface, outname); cairo_destroy (cr); cairo_surface_destroy (surface); return 0; }
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 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); } //}}}
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; }
int read_from_file(void *in_file, double *buffer, size_t count) { return sf_read_double((SNDFILE *)in_file, buffer, count); }