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;
}
Example #2
0
  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);
  }
Example #3
0
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 */
Example #5
0
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 */
Example #6
0
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 */
Example #7
0
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 */
Example #8
0
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;
}
Example #9
0
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 + "!");
}
Example #10
0
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;
}
Example #12
0
sf_count_t WriteWaveFile::WriteDouble(double *ptr, sf_count_t items)
{
  return (sf_write_double(sffile, ptr, items));
}
Example #13
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 */
Example #14
0
 int Soundfile::writeFrames(double *inputFrames, int samples)
 {
   return sf_write_double(sndfile, inputFrames, samples);
 }
Example #15
0
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 */
Example #17
0
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);
} //}}}