void AudioFileSndfile::write(const void* buffer, unsigned frames) { if (!_handle || (_mode != ModeWrite && _mode != ModeReadWrite)) { RUNTIME_ERROR("Attempt to write file not opened for writing."); } flushChunks(); sf_count_t count; switch (_info.sampleType) { case Sound::Type::Float32: case Sound::Type::Int24E: count = sf_writef_float(_handle.get(), static_cast<const Sound::Float32*>(buffer), frames); break; case Sound::Type::Float64: count = sf_writef_double(_handle.get(), static_cast<const Sound::Float64*>(buffer), frames); break; case Sound::Type::Int8: count = sf_write_raw(_handle.get(), buffer, frames * _info.channels); break; case Sound::Type::Int16: count = sf_writef_short(_handle.get(), static_cast<const Sound::Int16*>(buffer), frames); break; case Sound::Type::Int32: count = sf_writef_int(_handle.get(), static_cast<const Sound::Int32*>(buffer), frames); break; case Sound::Type::Int64: case Sound::Type::Precise: case Sound::Type::Count: RUNTIME_ERROR("Writing for this sample format is not supported"); } }
// // Scaling p from 16000 -> 48000 is simple, juast add zeros and filter void audioSink::audioOut_16000 (int16_t *V, int32_t amount) { float *buffer = (float *)alloca (6 * amount * sizeof (float)); int32_t i; int32_t available = _O_Buffer -> GetRingBufferWriteAvailable (); amount = 3 * amount; if (2 * amount > available) amount = (available / 2) & ~01; for (i = 0; i < amount / 3; i ++) { DSPCOMPLEX help = DSPCOMPLEX (0, 0); help = DSPCOMPLEX (float (V [2 * i]) / 32767.0, float (V [2 * i + 1]) / 32767.0); help = f_16000 -> Pass (help); buffer [6 * i] = real (help); buffer [6 * i + 1] = imag (help); help = f_16000 -> Pass (DSPCOMPLEX (0, 0)); buffer [6 * i + 2] = real (help); buffer [6 * i + 3] = imag (help); help = f_16000 -> Pass (DSPCOMPLEX (0, 0)); buffer [6 * i + 4] = real (help); buffer [6 * i + 5] = imag (help); } if (dumpFile != NULL) sf_writef_float (dumpFile, buffer, amount); _O_Buffer -> putDataIntoBuffer (buffer, 2 * amount); }
// // Conversion from 32 -> 48 is by first converting to 96000 // and then back to 48000 void audioSink::audioOut_32000 (int16_t *V, int32_t amount) { DSPCOMPLEX *buffer_1 = (DSPCOMPLEX *)alloca (3 * amount * sizeof (DSPCOMPLEX)); float *buffer = (float *)alloca (2 * 3 * amount / 2 * sizeof (float)); int32_t i; for (i = 0; i < amount; i ++) { DSPCOMPLEX help = DSPCOMPLEX (float (V [2 * i]) / 32767.0, float (V [2 * i + 1]) / 32767.0); buffer_1 [3 * i + 0] = f_32000 -> Pass (help); buffer_1 [3 * i + 1] = f_32000 -> Pass (DSPCOMPLEX (0, 0)); buffer_1 [3 * i + 2] = f_32000 -> Pass (DSPCOMPLEX (0, 0)); } // // Note that although we use "2 * i" for index left and right // they mean different things for (i = 0; i < 3 * amount / 2; i ++) { buffer [2 * i] = real (buffer_1 [2 * i]); buffer [2 * i + 1] = imag (buffer_1 [2 * i]); } if (dumpFile != NULL) sf_writef_float (dumpFile, buffer, 3 * amount / 2); _O_Buffer -> putDataIntoBuffer (buffer, 3 * amount); }
int SoundFile::write(float* data, uint32_t frames) { int i; uint32_t k; float *p, v; if(_readWriteMode != eRwModeWrite) return eErrorRwMode; if(_bitDepth != eBitDepthFloat) { for(i = 0; i < _nbChannels; i++) { p = data + i; for(k = 0; k < frames; k++) { v = *p; if(v > 1.0f) v = 1.0f; else if(v < -1.0f) v = -1.0f; *p = v; p += _nbChannels; } } } return sf_writef_float(_sndfile, data, frames); }
// Has been used for debugging. Not sure if I planned to use it for anything else. void SAMPLER_save_sample(struct SoundPlugin *plugin, const wchar_t *filename, int sample_number){ Data *data = (Data*)plugin->data; const Sample *sample = &data->samples[sample_number]; SF_INFO sf_info; memset(&sf_info,0,sizeof(sf_info)); sf_info.samplerate = 22050; sf_info.channels = 1; sf_info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; if(sf_format_check(&sf_info)==0){ fprintf (stderr, "\nFileformat not supported by libsndfile.\n"); return; } SNDFILE *sndfile = sf_open(STRING_get_chars(filename),SFM_WRITE,&sf_info); if(sndfile==NULL){ fprintf(stderr,"could not open file\n"); return; } sf_writef_float(sndfile,sample->sound,sample->num_frames); sf_close(sndfile); }
bool WavFileWriter::writeSamples(float **samples, size_t count) { if (!m_file) { m_error = QString("Failed to write model to audio file '%1': File not open") .arg(m_path); return false; } float *b = new float[count * m_channels]; for (size_t i = 0; i < count; ++i) { for (size_t c = 0; c < m_channels; ++c) { b[i * m_channels + c] = samples[c][i]; } } sf_count_t written = sf_writef_float(m_file, b, count); delete[] b; if (written < count) { m_error = QString("Only wrote %1 of %2 frames") .arg(written).arg(count); } return isOK(); }
int SoundFile::write (float *data, uint32_t frames) { int i; uint32_t k; float *p, v; if (_mode != MODE_WRITE) return ERR_MODE; if (_form != FORM_FLOAT) { for (i = 0; i < _chan; i++) { p = data + i; for (k = 0; k < frames; k++) { v = *p; if (v > 1.0f) v = 1.0f; else if (v < -1.0f) v = -1.0f; *p = v; p += _chan; } } } return sf_writef_float (_sndfile, data, frames); }
void pcap_callback(u_char* args, const struct pcap_pkthdr* packet_header, const u_char* packet) { unsigned char* test_stream_id; struct ethernet_header* eth_header; uint32_t* mybuf; uint32_t frame[CHANNELS]; jack_default_audio_sample_t jackframe[CHANNELS]; int cnt; static int total; eth_header = (struct ethernet_header*)(packet); if (0 != memcmp(ETHER_TYPE,eth_header->type,sizeof(eth_header->type))) { return; } test_stream_id = (unsigned char*)(packet + ETHERNET_HEADER_SIZE + SEVENTEEN22_HEADER_PART1_SIZE); if (0 != memcmp(test_stream_id, stream_id, STREAM_ID_SIZE)) { return; } mybuf = (uint32_t*) (packet + HEADER_SIZE); for(int i = 0; i < SAMPLES_PER_FRAME * CHANNELS; i+=CHANNELS) { memcpy(&frame[0], &mybuf[i], sizeof(frame)); for(int j = 0; j < CHANNELS; j++) { frame[j] = ntohl(frame[j]); /* convert to host-byte order */ frame[j] &= 0x00ffffff; /* ignore leading label */ frame[j] <<= 8; /* left-align remaining PCM-24 sample */ jackframe[j] = ((int32_t)frame[j])/(float)(MAX_SAMPLE_VALUE); } if ((cnt = jack_ringbuffer_write_space(ringbuffer)) >= SAMPLE_SIZE * CHANNELS) { jack_ringbuffer_write(ringbuffer, (void*)&jackframe[0], SAMPLE_SIZE * CHANNELS); } else { fprintf(stdout, "Only %i bytes available after %i samples.\n", cnt, total); } if (jack_ringbuffer_write_space(ringbuffer) <= SAMPLE_SIZE * CHANNELS * DEFAULT_RINGBUFFER_SIZE / 4) { /** Ringbuffer has only 25% or less write space available, it's time to tell jackd to read some data. */ ready = 1; } #ifdef LIBSND sf_writef_float(snd_file, jackframe, 1); #endif } }
int copy_partial_sndfile(SNDFILE* sndfile,SF_INFO* info_in,SNDFILE* out,int in, size_t sample_length) { if (!info_in->seekable) { fprintf(stderr,"Error: Base file not seekable"); return 1; } long real_in = in < 0?0:in; sf_seek(sndfile,real_in,SEEK_SET); long end = in + sample_length; if (((size_t)end) > info_in->frames) { end = info_in->frames; } size_t j = 0; float* frame =(float*) std::malloc(sizeof(float)*info_in->channels*1024); memset(frame,0,sizeof(float)*info_in->channels*1024); for(long i = in; i < 0; i++) { sf_writef_float(out,frame,1); j++; } for(size_t i = 0; i < end ; i+=1024) { size_t frames_to_transfer = end -i; frames_to_transfer = frames_to_transfer>1024?1024:frames_to_transfer; sf_readf_float(sndfile,frame,frames_to_transfer); sf_writef_float(out,frame,frames_to_transfer); j+=frames_to_transfer; } std::memset(frame,0,sizeof(float)*info_in->channels*1024); for(; j < sample_length; j++) { sf_writef_float(out,frame,1); } std::free(frame); return 0; }
int SNDFile::writeFile(float* buffer, SF_INFO sfInfo, string outName) { outFile = sf_open(outName.c_str(), SFM_WRITE, &sfInfo); if (outFile == NULL) { std::cout << "Error writing file" << std::endl; return -1; } sf_writef_float(outFile, buffer, sfInfo.frames); sf_close(outFile); return 0; }
/** write /nframes/ from /buf/ to soundfile. Should be interleaved for * the appropriate number of channels */ nframes_t Audio_File_SF::write ( sample_t *buf, nframes_t nframes ) { _peaks.write( buf, nframes ); // lock(); nframes_t l = sf_writef_float( _in, buf, nframes ); _length += l; // unlock(); return l; }
static void * disk_thread (void *arg) { jack_thread_info_t *info = (jack_thread_info_t *) arg; static jack_nframes_t total_captured = 0; jack_nframes_t samples_per_frame = info->channels; size_t bytes_per_frame = samples_per_frame * sample_size; void *framebuf = malloc (bytes_per_frame); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_mutex_lock (&disk_thread_lock); info->status = 0; while (1) { /* Write the data one frame at a time. This is * inefficient, but makes things simpler. */ while (info->can_capture && (jack_ringbuffer_read_space (rb) >= bytes_per_frame)) { jack_ringbuffer_read (rb, framebuf, bytes_per_frame); if (sf_writef_float (info->sf, framebuf, 1) != 1) { char errstr[256]; sf_error_str (0, errstr, sizeof (errstr) - 1); fprintf (stderr, "cannot write sndfile (%s)\n", errstr); info->status = EIO; /* write failed */ goto done; } if (++total_captured >= info->duration) { printf ("disk thread finished\n"); goto done; } } /* wait until process() signals more data */ pthread_cond_wait (&data_ready, &disk_thread_lock); } done: pthread_mutex_unlock (&disk_thread_lock); free (framebuf); return 0; }
void test_writef_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t frames, int line_num) { sf_count_t count ; if ((count = sf_writef_float (file, test, frames)) != frames) { printf ("\n\nLine %d", line_num) ; if (pass > 0) printf (" (pass %d)", pass) ; printf (" : sf_writef_float failed with short writef (%ld => %ld).\n", SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ; fflush (stdout) ; puts (sf_strerror (file)) ; exit (1) ; } ; return ; } /* test_writef_float */
bool BufWriteCmd::Stage2() { #ifdef NO_LIBSNDFILE return false; #else SndBuf *buf = World_GetNRTBuf(mWorld, mBufIndex); int framesToEnd = buf->frames - mBufOffset; if (framesToEnd < 0) framesToEnd = 0; mFileInfo.samplerate = (int)buf->samplerate; mFileInfo.channels = buf->channels; SNDFILE* sf = sf_open(mFilename, SFM_WRITE, &mFileInfo); if (!sf) { char str[512]; sprintf(str, "File '%s' could not be opened: %s\n", mFilename, sf_strerror(NULL)); SendFailureWithIntValue(&mReplyAddress, "/b_write", str, mBufIndex); //SendFailure(&mReplyAddress, "/b_write", str); scprintf(str); return false; } if (mNumFrames < 0 || mNumFrames > buf->frames) mNumFrames = buf->frames; if (mNumFrames > framesToEnd) mNumFrames = framesToEnd; sf_command(sf, SFC_SET_CLIPPING, NULL, SF_TRUE); // choose clipping rather than wraparound for integer-format files if (mNumFrames > 0) { sf_writef_float(sf, buf->data + (mBufOffset * buf->channels), mNumFrames); } if(buf->sndfile) sf_close(buf->sndfile); if (mLeaveFileOpen) { buf->sndfile = sf; } else { sf_close(sf); buf->sndfile = 0; } return true; #endif }
PRIVATE int output_fragment(SNDFILE *f, SAMPLE *l_buf, SAMPLE *r_buf, int length) { SAMPLE *outbuf; int buflen = length * sizeof(SAMPLE) * 2; int i; if (length <= 0) return 0; outbuf = g_alloca(buflen); for (i = 0; i < length; i++) { outbuf[i<<1] = l_buf[i]; outbuf[(i<<1) + 1] = r_buf[i]; } // i = sf_writef_double(f, outbuf, length); i = sf_writef_float(f, outbuf, length); return i; }
bool SOUNDFILESAVER_write(float **outputs, int num_frames){ PaUtil_FullMemoryBarrier(); if(g_save_state==BEFORE_WRITING && is_playing()==false) return true; if(g_save_state==AFTER_WRITING) return true; bool ret=true; int i; float interleaved_data[num_frames*2]; int pos=0; for(i=0;i<num_frames;i++){ interleaved_data[pos++] = outputs[0][i]; interleaved_data[pos++] = outputs[1][i]; } //printf("Writing %d frames\n",num_frames); if(sf_writef_float(g_sndfile, interleaved_data, num_frames) != num_frames){ g_saving_was_successful = false; ret = false; } if(g_save_state==IS_WRITING){ if(is_playing()==false){ g_save_state=POST_WRITING; } } if(g_save_state==POST_WRITING){ g_post_writing_left -= (float)num_frames/MIXER_get_sample_rate(); if(g_post_writing_left <= 0.0f){ stop_writing(); g_save_state=AFTER_WRITING; } } return ret; }
/*! @function wavwrite @abstract Write a SIGNAL (audio file) to disk @discussion Utility function that writes the contents of a SIGNAL structure to disk. It uses and depends on the libsndfile API. @param OUTPUTFILENAME The filename to use for the output file. If no path is provided the file will be saved at the location the executable resides. @param OUPUT A SIGNAL structure containing the audio data to write to disk. @result SfError a libsndfile error code (an integer). */ SfError wavwrite(const char* outputFileName, SIGNAL *output) { int err=0; SNDFILE* file=NULL; SF_INFO info; sf_count_t frameswritten=0; info.samplerate=output->samplerate; info.channels=output->channels; info.format=output->format; //Check if SF_INFO struct is valid //err=sf_format_check(&info); //checkErr(err,kSndFileSystem,"wavwrite: format checking code"); //Open a file for writting if(!(file=sf_open(outputFileName, SFM_WRITE, &info))) { printf("Failed to open %s for writting!\n",outputFileName); err=sf_error(file); checkErr(err,kSndFileSystem,"wavwrite: opening file"); return err;//Return at this point because the file could not open so we cannot write anything! } //Write audio data to audio file. frameswritten=sf_writef_float(file, output->data, output->frames); if(frameswritten!=output->frames) { err=sf_error(file); checkErr(err,kSndFileSystem,"wavwrite: writting data to file"); } //Close audio file. err=sf_close(file); checkErr(err,kSndFileSystem,"wavwrite: closing file"); return err; }
void audioSink::audioOut_48000 (int16_t *V, int32_t amount) { float *buffer = (float *)alloca (2 * amount * sizeof (float)); int32_t i, n; int32_t available = _O_Buffer -> GetRingBufferWriteAvailable (); n = amount; if (2 * n > available) n = (available / 2) & ~01; for (i = 0; i < amount; i ++) { buffer [2 * i] = float (V [2 * i]) / 32767.0; buffer [2 * i + 1] = float (V [2 * i + 1]) / 32767.0; } if (dumpFile != NULL) sf_writef_float (dumpFile, buffer, amount); // // O_Buffer contains floats, so a double "amount" (which was the // count of IQ samples _O_Buffer -> putDataIntoBuffer (buffer, 2 * amount); }
static switch_status_t sndfile_file_write(switch_file_handle_t *handle, void *data, size_t *len) { size_t inlen = *len; sndfile_context *context = handle->private_info; if (switch_test_flag(handle, SWITCH_FILE_DATA_RAW)) { *len = (size_t) sf_write_raw(context->handle, data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_INT)) { *len = (size_t) sf_writef_int(context->handle, (int *) data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) { *len = (size_t) sf_writef_short(context->handle, (short *) data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_FLOAT)) { *len = (size_t) sf_writef_float(context->handle, (float *) data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_DOUBLE)) { *len = (size_t) sf_writef_double(context->handle, (double *) data, inlen); } else { *len = (size_t) sf_writef_int(context->handle, (int *) data, inlen); } handle->sample_count += *len; return sf_error(context->handle) == SF_ERR_NO_ERROR ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; }
/* * call-seq: * snd.write(buf) => integer * * Writes the entire contents of the given buffer to the sound and returns the * number of frames written. */ static VALUE ra_sound_write(VALUE self, VALUE buf) { RA_SOUND *snd; Data_Get_Struct(self, RA_SOUND, snd); if(snd->closed) rb_raise(eRubyAudioError, "closed sound"); // Get buffer struct RA_BUFFER *b; Data_Get_Struct(buf, RA_BUFFER, b); // Get info struct SF_INFO *info; Data_Get_Struct(snd->info, SF_INFO, info); // Check buffer channels matches actual channels if(b->channels != info->channels) { rb_raise(eRubyAudioError, "channel count mismatch: %d vs %d", b->channels, info->channels); } // Write data sf_count_t written; switch(b->type) { case RA_BUFFER_TYPE_SHORT: written = sf_writef_short(snd->snd, b->data, b->real_size); break; case RA_BUFFER_TYPE_INT: written = sf_writef_int(snd->snd, b->data, b->real_size); break; case RA_BUFFER_TYPE_FLOAT: written = sf_writef_float(snd->snd, b->data, b->real_size); break; case RA_BUFFER_TYPE_DOUBLE: written = sf_writef_double(snd->snd, b->data, b->real_size); break; } return OFFT2NUM(written); }
static ssize_t sa_sndfile_write( simpleaudio *sa, void *buf, size_t nframes ) { // fprintf(stderr, "sf_write: nframes=%ld\n", nframes); SNDFILE *s = (SNDFILE *)sa->backend_handle; int n; switch ( sa->format ) { case SA_SAMPLE_FORMAT_FLOAT: n = sf_writef_float(s, buf, nframes); break; case SA_SAMPLE_FORMAT_S16: n = sf_writef_short(s, buf, nframes); break; default: assert(0); break; } if ( n < 0 ) { fprintf(stderr, "sf_write: "); sf_perror(s); return -1; } return n; }
static void beat_detect (SNDFILE * file, const SF_INFO * sfinfo) { static float data [16 * 1024] ; static float env [CHANNEL_COUNT * 16 * 1024] ; fir_hilbert_t hilbert ; int read_count ; memset (&hilbert, 0, sizeof (hilbert)) ; SNDFILE * outa, *outb ; SF_INFO outinfo = *sfinfo ; outinfo.channels = CHANNEL_COUNT ; outinfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT ; if ((outa = sf_open ("/tmp/envelope.wav", SFM_WRITE, &outinfo)) == NULL) { puts ("Open outa failed.") ; exit (1) ; } ; if ((outb = sf_open ("/tmp/peaks.wav", SFM_WRITE, &outinfo)) == NULL) { puts ("Open outa failed.") ; exit (1) ; } ; while ((read_count = sf_read_float (file, data, ARRAY_LEN (data))) > 0) { int env_count ; env_count = hilbert_mag_filter (&hilbert, data, ARRAY_LEN (data), env, sfinfo->samplerate) ; sf_writef_float (outa, env, env_count) ; sf_seek (file, env_count - read_count, SEEK_CUR) ; } ; sf_close (outa) ; sf_close (outb) ; } /* beat_detect */
int writefile(SAMPLE *recording,int totalFrames) { SNDFILE *file ; SF_INFO sfinfo ; //memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = SAMPLE_RATE ; sfinfo.frames = totalFrames ; sfinfo.channels = NUM_CHANNELS ; sfinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_32) ; if (! (file = sf_open ("pyplot/recorded.wav", SFM_WRITE, &sfinfo))) { printf ("Error : Not able to open output file.\n") ; return 1 ; } if (sf_writef_float (file, (float *)recording, totalFrames) != totalFrames) puts (sf_strerror (file)) ; sf_close (file) ; return 0 ; }
int main(int argc, char *argv[]) { SNDFILE* in_sf; SNDFILE* out_sf; SF_INFO in_info; SF_INFO out_info; unsigned int nAppend = 0; // number of frames to append beyond input file if (argc < 3) { fprintf(stderr,"*** USAGE: %s input_soundfile output_soundfile\n",argv[0]); exit(1); } nAppend = loptrm(&argc, argv, "--continue", "-c", 0); CMDUI* interface = new CMDUI(argc, argv); DSP.buildUserInterface(interface); interface->process_command(); // open input file in_info.format = 0; in_sf = sf_open(interface->input_file(), SFM_READ, &in_info); if (in_sf == NULL) { fprintf(stderr,"*** Input file not found.\n"); sf_perror(in_sf); exit(1); } // open output file out_info = in_info; out_info.format = in_info.format; out_info.channels = DSP.getNumOutputs(); out_sf = sf_open(interface->output_file(), SFM_WRITE, &out_info); if (out_sf == NULL) { fprintf(stderr,"*** Cannot write output file.\n"); sf_perror(out_sf); exit(1); } // create separator and interleaver Separator sep(kFrames, in_info.channels, DSP.getNumInputs()); Interleaver ilv(kFrames, DSP.getNumOutputs()); // init signal processor DSP.init(in_info.samplerate); //DSP.buildUserInterface(interface); interface->process_init(); // process all samples int nbf; do { nbf = READ_SAMPLE(in_sf, sep.input(), kFrames); sep.separate(); DSP.compute(nbf, sep.outputs(), ilv.inputs()); ilv.interleave(); sf_writef_float(out_sf, ilv.output(), nbf); //sf_write_raw(out_sf, ilv.output(), nbf); } while (nbf == kFrames); sf_close(in_sf); // compute tail, if any if (nAppend>0) { FAUSTFLOAT *input = (FAUSTFLOAT*) calloc(nAppend * DSP.getNumInputs(), sizeof(FAUSTFLOAT)); FAUSTFLOAT *inputs[1] = { input }; Interleaver ailv(nAppend, DSP.getNumOutputs()); DSP.compute(nAppend, inputs, ailv.inputs()); ailv.interleave(); sf_writef_float(out_sf, ailv.output(), nAppend); } sf_close(out_sf); }
void World_NonRealTimeSynthesis(struct World *world, WorldOptions *inOptions) { if (inOptions->mLoadGraphDefs) { World_LoadGraphDefs(world); } int bufLength = world->mBufLength; int fileBufFrames = inOptions->mPreferredHardwareBufferFrameSize; if (fileBufFrames <= 0) fileBufFrames = 8192; int bufMultiple = (fileBufFrames + bufLength - 1) / bufLength; fileBufFrames = bufMultiple * bufLength; // batch process non real time audio if (!inOptions->mNonRealTimeOutputFilename) throw std::runtime_error("Non real time output filename is NULL.\n"); SF_INFO inputFileInfo, outputFileInfo; float *inputFileBuf = 0; float *outputFileBuf = 0; int numInputChannels = 0; int numOutputChannels; outputFileInfo.samplerate = inOptions->mPreferredSampleRate; numOutputChannels = outputFileInfo.channels = world->mNumOutputs; sndfileFormatInfoFromStrings(&outputFileInfo, inOptions->mNonRealTimeOutputHeaderFormat, inOptions->mNonRealTimeOutputSampleFormat); world->hw->mNRTOutputFile = sf_open(inOptions->mNonRealTimeOutputFilename, SFM_WRITE, &outputFileInfo); sf_command(world->hw->mNRTOutputFile, SFC_SET_CLIPPING, NULL, SF_TRUE); if (!world->hw->mNRTOutputFile) throw std::runtime_error("Couldn't open non real time output file.\n"); outputFileBuf = (float*)calloc(1, world->mNumOutputs * fileBufFrames * sizeof(float)); if (inOptions->mNonRealTimeInputFilename) { world->hw->mNRTInputFile = sf_open(inOptions->mNonRealTimeInputFilename, SFM_READ, &inputFileInfo); if (!world->hw->mNRTInputFile) throw std::runtime_error("Couldn't open non real time input file.\n"); inputFileBuf = (float*)calloc(1, inputFileInfo.channels * fileBufFrames * sizeof(float)); if (world->mNumInputs != (uint32)inputFileInfo.channels) scprintf("WARNING: input file channels didn't match number of inputs specified in options.\n"); numInputChannels = world->mNumInputs = inputFileInfo.channels; // force it. if (inputFileInfo.samplerate != (int)inOptions->mPreferredSampleRate) scprintf("WARNING: input file sample rate does not equal output sample rate.\n"); } else { world->hw->mNRTInputFile = 0; } FILE *cmdFile; if (inOptions->mNonRealTimeCmdFilename) { #ifdef _WIN32 cmdFile = fopen(inOptions->mNonRealTimeCmdFilename, "rb"); #else cmdFile = fopen(inOptions->mNonRealTimeCmdFilename, "r"); #endif } else cmdFile = stdin; if (!cmdFile) throw std::runtime_error("Couldn't open non real time command file.\n"); OSC_Packet packet; memset(&packet, 0, sizeof(packet)); packet.mData = (char *)malloc(8192); packet.mIsBundle = true; packet.mReplyAddr.mReplyFunc = null_reply_func; int64 schedTime; if (nextOSCPacket(cmdFile, &packet, schedTime)) throw std::runtime_error("command file empty.\n"); int64 prevTime = schedTime; World_SetSampleRate(world, inOptions->mPreferredSampleRate); World_Start(world); int64 oscTime = 0; double oscToSeconds = 1. / pow(2.,32.); double oscToSamples = inOptions->mPreferredSampleRate * oscToSeconds; int64 oscInc = (int64)((double)bufLength / oscToSamples); if(inOptions->mVerbosity >= 0) { printf("start time %g\n", schedTime * oscToSeconds); } bool run = true; int inBufStep = numInputChannels * bufLength; int outBufStep = numOutputChannels * bufLength; float* inputBuses = world->mAudioBus + world->mNumOutputs * bufLength; float* outputBuses = world->mAudioBus; int32* inputTouched = world->mAudioBusTouched + world->mNumOutputs; int32* outputTouched = world->mAudioBusTouched; for (; run;) { int bufFramesCalculated = 0; float* inBufPos = inputFileBuf; float* outBufPos = outputFileBuf; if (world->hw->mNRTInputFile) { int framesRead = sf_readf_float(world->hw->mNRTInputFile, inputFileBuf, fileBufFrames); if (framesRead < fileBufFrames) { memset(inputFileBuf + framesRead * numInputChannels, 0, (fileBufFrames - framesRead) * numInputChannels * sizeof(float)); } } for (int i=0; i<bufMultiple && run; ++i) { int bufCounter = world->mBufCounter; // deinterleave input to input buses if (inputFileBuf) { float *inBus = inputBuses; for (int j=0; j<numInputChannels; ++j, inBus += bufLength) { float *inFileBufPtr = inBufPos + j; for (int k=0; k<bufLength; ++k) { inBus[k] = *inFileBufPtr; inFileBufPtr += numInputChannels; } inputTouched[j] = bufCounter; } } // execute ready commands int64 nextTime = oscTime + oscInc; while (schedTime <= nextTime) { float diffTime = (float)(schedTime - oscTime) * oscToSamples + 0.5; float diffTimeFloor = floor(diffTime); world->mSampleOffset = (int)diffTimeFloor; world->mSubsampleOffset = diffTime - diffTimeFloor; if (world->mSampleOffset < 0) world->mSampleOffset = 0; else if (world->mSampleOffset >= bufLength) world->mSampleOffset = bufLength-1; PerformOSCBundle(world, &packet); if (nextOSCPacket(cmdFile, &packet, schedTime)) { run = false; break; } if(inOptions->mVerbosity >= 0) { printf("nextOSCPacket %g\n", schedTime * oscToSeconds); } if (schedTime < prevTime) { scprintf("ERROR: Packet time stamps out-of-order.\n"); run = false; goto Bail; } prevTime = schedTime; } World_Run(world); // interleave output to output buffer float *outBus = outputBuses; for (int j=0; j<numOutputChannels; ++j, outBus += bufLength) { float *outFileBufPtr = outBufPos + j; if (outputTouched[j] == bufCounter) { for (int k=0; k<bufLength; ++k) { *outFileBufPtr = outBus[k]; outFileBufPtr += numOutputChannels; } } else { for (int k=0; k<bufLength; ++k) { *outFileBufPtr = 0.f; outFileBufPtr += numOutputChannels; } } } bufFramesCalculated += bufLength; inBufPos += inBufStep; outBufPos += outBufStep; world->mBufCounter++; oscTime = nextTime; } Bail: // write output sf_writef_float(world->hw->mNRTOutputFile, outputFileBuf, bufFramesCalculated); } if (cmdFile != stdin) fclose(cmdFile); sf_close(world->hw->mNRTOutputFile); world->hw->mNRTOutputFile = 0; if (world->hw->mNRTInputFile) { sf_close(world->hw->mNRTInputFile); world->hw->mNRTInputFile = 0; } free(packet.mData); World_Cleanup(world,true); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //-------------------------------------------- // VARIABLES //-------------------------------------------- //-- // samples and rate //-- // NOTE: this includes the samples array pointer, number of channels and samples, and rate void *X; int n, ch, r, e; //-- // output file name //-- char *f; int len; //-- // format and encoding //-- int fmt_code, enc_code; //-- // libsndfile structures //-- SNDFILE *out_file; SF_INFO out_info; mxClassID cls; //-------------------------------------------- // INPUT //-------------------------------------------- // TODO: add some check on the number of channels and samples //-------------------------------- // samples and rate //-------------------------------- X = mxGetPr(prhs[0]); cls = mxGetClassID(prhs[0]); n = mxGetN(prhs[0]); ch = mxGetM(prhs[0]); r = (int) mxGetScalar(prhs[1]); //-------------------------------- // output file //-------------------------------- len = mxGetM(prhs[2]) * mxGetN(prhs[2]) + 1; f = mxCalloc(len, sizeof(char)); mxGetString(prhs[2], f, len); //-------------------------------- // format and encoding //-------------------------------- // NOTE: although we could extract the format from the file name it it easier in MATLAB fmt_code = (int) mxGetScalar(prhs[3]); enc_code = (int) mxGetScalar(prhs[4]); //-------------------------------------------- // COMPUTATION //-------------------------------------------- //-------------------------------- // fill info structure //-------------------------------- out_info.frames = n; out_info.channels = ch; out_info.samplerate = r; out_info.sections = 1; out_info.seekable = 1; // NOTE: look at 'sndfile.h' for the meanings of these switch (fmt_code) { case 0: fmt_code = SF_FORMAT_WAV; break; case 1: fmt_code = SF_FORMAT_AIFF; break; case 2: fmt_code = SF_FORMAT_AU; break; case 3: fmt_code = SF_FORMAT_W64; break; case 4: fmt_code = SF_FORMAT_FLAC; break; default: mexErrMsgTxt("Unsupported major file format."); } // NOTE: look at 'sndfile.h' for the meanings of these switch (enc_code) { case 0: if (fmt_code == SF_FORMAT_AU) { mexErrMsgTxt("Unsupported encoding for major file format."); } enc_code = SF_FORMAT_PCM_U8; break; case 1: if ((fmt_code == SF_FORMAT_WAV) || (fmt_code == SF_FORMAT_WAV)) { mexErrMsgTxt("Unsupported encoding for major file format."); } enc_code = SF_FORMAT_PCM_S8; break; case 2: enc_code = SF_FORMAT_PCM_16; break; case 3: enc_code = SF_FORMAT_PCM_24; break; case 4: enc_code = SF_FORMAT_PCM_32; break; case 5: enc_code = SF_FORMAT_FLOAT; break; case 6: enc_code = SF_FORMAT_DOUBLE; break; case 7: enc_code = SF_FORMAT_ULAW; break; case 8: enc_code = SF_FORMAT_ALAW; break; case 9: if ((fmt_code == SF_FORMAT_AIFF) || (fmt_code == SF_FORMAT_AU)) { mexErrMsgTxt("Unsupported encoding for major file format."); } enc_code = SF_FORMAT_IMA_ADPCM; break; case 10: if ((fmt_code == SF_FORMAT_AIFF) || (fmt_code == SF_FORMAT_AU)) { mexErrMsgTxt("Unsupported encoding for major file format."); } enc_code = SF_FORMAT_MS_ADPCM; break; case 11: if (fmt_code == SF_FORMAT_AU) { mexErrMsgTxt("Unsupported encoding for major file format."); } enc_code = SF_FORMAT_GSM610; break; default: mexErrMsgTxt("Unsupported encoding."); } out_info.format = fmt_code | enc_code; if (!sf_format_check(&out_info)) mexErrMsgTxt("failed format check."); //-------------------------------- // create output file //-------------------------------- //-- // open output file (create if needed) //-- out_file = sf_open (f, SFM_WRITE, &out_info); if (out_file == NULL) { // grab log buffer (very informative about errors) char buffer [2048] ; sf_command (out_file, SFC_GET_LOG_INFO, buffer, sizeof (buffer)) ; mexPrintf("%s\n", buffer); // there must be an error, display it, and break. mexErrMsgTxt(sf_error_number(sf_error(out_file))) ; } //-- // write samples to output file //-- // NOTE: set normalization to true, this assumes samples are in the -1 to 1 range switch (cls){ case (mxDOUBLE_CLASS): sf_command (out_file, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE); sf_writef_double (out_file, (double *) X, n); break; case (mxSINGLE_CLASS): sf_command (out_file, SFC_SET_NORM_FLOAT, NULL, SF_TRUE); sf_writef_float (out_file, (float *) X, n); break; default: mexErrMsgTxt("Unsupported class.\n"); } //-- // close file //-- sf_close (out_file); }
void EchonestInterface::appendToCodegenBuffer(const float *buffer, unsigned long numFrames) { sf_writef_float(codegenBuffer, buffer, numFrames); codegenCurrentNumFrames += numFrames; }
// Main entrypoint int main(int argc, char** argv) { // Soundfile pointers (input file, output file) SNDFILE *psf_in, *psf_out; // Soundfile information structts (input, output) SF_INFO *psfinfo_in, *psfinfo_out; // Buffer of floats float *buffer; // Counter variable (for keeping track of processed frames/samples) sf_count_t count = 0; // Number of channels int numChannels; // Allocate memory for SF_INFO structures dynamically psfinfo_in = (SF_INFO *) malloc( sizeof(SF_INFO) ); psfinfo_out = (SF_INFO *) malloc( sizeof(SF_INFO) ); // Open input file for reading // argv[1] is passed as the path to the input file // i.e. the first argument typed after the program's name by the user if( !(psf_in = sf_open(argv[1], SFM_READ, psfinfo_in)) ) { printf("Error opening input file\n"); exit(-1); } // Check to see if input file's format is AIFF // A bitwise AND (&) between the 'format' member of the info struct and the SF_FORMAT_TYPEMASK bitmask // gives us the base format of the file if((psfinfo_in->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) { // Dynamically allocate buffer memory (BUFFRAMES macro by the size of our data type) buffer = (float *) malloc( sizeof(float) * BUFFRAMES ); // Now we initialise the SF_INFO structure for the output file with the same sampling rate psfinfo_out->samplerate = psfinfo_in->samplerate; // Same number of channels psfinfo_out->channels = psfinfo_in->channels; numChannels = psfinfo_in->channels; // WAV format instead of AIFF with the same precision // We specify the base format as WAV then set the precision using the SF_FORMAT_SUBMASK bitmask (&) psfinfo_out->format = SF_FORMAT_WAV | (psfinfo_in->format & SF_FORMAT_SUBMASK); // Open the output file if( !( psf_out = sf_open(argv[2], SFM_WRITE,psfinfo_out) ) ) { printf("error opening output file\n"); exit(-1); } // Copy the data from one to the other, frame by frame // Do-while loop ensures that at least one attempt is made // Loop keeps going until count returns 0 (i.e.; Ran out of samples from input file [Reached end of file] ) do { // Store the number of frames read in the count variable // sf_readf_float reads the samples in frames of floats from psf_in // A buffer of 512 will hold 256 stereo frames // Divide buffer size by the number of frames to tell libsndfile how many frames (items) to grab count = sf_readf_float(psf_in, buffer, BUFFRAMES / numChannels); // Take the samples that we just read from the buffer and write them to the output file (psf_out) // We write 'count' samples to the output, since that's how many we grabbed at the input sf_writef_float(psf_out, buffer, count); } while(count); // Close both of the files since we're done with them sf_close(psf_in); sf_close(psf_out); // Free the memory that we allocated dynamically free(psfinfo_in); // Free input info struct memory free(psfinfo_out); // Free output info struct memory free(buffer); // Free the buffer memory // Return 0 for success return 0; } else { // Give an error if the input file was not an AIFF file printf("Not an AIFF file\n"); // Close the input file sf_close(psf_in); free(psfinfo_in); // Free input info struct memory free(psfinfo_out); // Free output info struct memory // There's something missing here.. Can you guess what? // Return 1 to indicate that a problem was encountered return 1; } }
static sf_count_t sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain, int normalize) { static float input [BUFFER_LEN] ; static float output [BUFFER_LEN] ; SRC_STATE *src_state ; SRC_DATA src_data ; int error ; double max = 0.0 ; sf_count_t output_count = 0 ; sf_seek (infile, 0, SEEK_SET) ; sf_seek (outfile, 0, SEEK_SET) ; /* Initialize the sample rate converter. */ if ((src_state = src_new (converter, channels, &error)) == NULL) { printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ; exit (1) ; } ; src_data.end_of_input = 0 ; /* Set this later. */ /* Start with zero to force load in while loop. */ src_data.input_frames = 0 ; src_data.data_in = input ; src_data.src_ratio = src_ratio ; src_data.data_out = output ; src_data.output_frames = BUFFER_LEN /channels ; while (1) { /* If the input buffer is empty, refill it. */ if (src_data.input_frames == 0) { src_data.input_frames = sf_readf_float (infile, input, BUFFER_LEN / channels) ; src_data.data_in = input ; /* The last read will not be a full buffer, so snd_of_input. */ if (src_data.input_frames < BUFFER_LEN / channels) src_data.end_of_input = SF_TRUE ; } ; if ((error = src_process (src_state, &src_data))) { printf ("\nError : %s\n", src_strerror (error)) ; exit (1) ; } ; /* Terminate if done. */ if (src_data.end_of_input && src_data.output_frames_gen == 0) break ; max = apply_gain (src_data.data_out, src_data.output_frames_gen, channels, max, *gain) ; /* Write output. */ sf_writef_float (outfile, output, src_data.output_frames_gen) ; output_count += src_data.output_frames_gen ; src_data.data_in += src_data.input_frames_used * channels ; src_data.input_frames -= src_data.input_frames_used ; } ; src_delete (src_state) ; if (normalize && max > 1.0) { *gain = 1.0 / max ; printf ("\nOutput has clipped. Restarting conversion to prevent clipping.\n\n") ; return -1 ; } ; return output_count ; } /* sample_rate_convert */
sf_count_t Audio_file_reader::sample_rate_convert (SNDFILE *sf_rs, int converter, double src_ratio, int channels, double * gain) { static float input [BUFFER_LEN] ; static float output [BUFFER_LEN] ; SRC_STATE *src_state ; SRC_DATA src_data ; int error ; sf_count_t output_count = 0 ; sf_seek (sf, 0, SEEK_SET) ; sf_seek (sf_rs, 0, SEEK_SET) ; /* Initialize the sample rate converter. */ if ((src_state = src_new (converter, channels, &error)) == NULL) { printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ; exit (1) ; } ; src_data.end_of_input = 0 ; /* Set this later. */ /* Start with zero to force load in while loop. */ src_data.input_frames = 0 ; src_data.data_in = input ; src_data.src_ratio = src_ratio ; src_data.data_out = output ; src_data.output_frames = BUFFER_LEN /channels ; while (1) { /* If the input buffer is empty, refill it. */ if (src_data.input_frames == 0) { src_data.input_frames = sf_readf_float (sf, input, BUFFER_LEN / channels) ; src_data.data_in = input ; /* The last read will not be a full buffer, so snd_of_input. */ if (src_data.input_frames < BUFFER_LEN / channels) src_data.end_of_input = SF_TRUE ; }; if ((error = src_process (src_state, &src_data))) { printf ("\nError : %s\n", src_strerror (error)) ; exit (1) ; } ; /* Terminate if done. */ if (src_data.end_of_input && src_data.output_frames_gen == 0) break ; /* Write output. */ sf_writef_float (sf_rs, output, src_data.output_frames_gen) ; output_count += src_data.output_frames_gen ; src_data.data_in += src_data.input_frames_used * channels ; src_data.input_frames -= src_data.input_frames_used ; } ; src_state = src_delete (src_state) ; return output_count ; } /* sample_rate_convert */