SNDFILE *sf_open(const char *path, int mode, SF_INFO *info) { if (path == NULL || info == NULL) return NULL; switch (mode) { case SFM_READ: return sf_open_read(path, info); case SFM_WRITE: return sf_open_write(path, info); default: return NULL; } }
static void stdout_test (char *str, int typemajor, int count) { static short data [BUFFER_LEN] ; SNDFILE *file ; SF_INFO sfinfo ; unsigned int k, total, this_write ; fprintf (stderr, " %-5s : writing %d samples to stdout ... ", str, count) ; sfinfo.samplerate = 44100 ; sfinfo.pcmbitwidth = 16 ; sfinfo.format = (typemajor | SF_FORMAT_PCM) ; sfinfo.channels = 1 ; sfinfo.samples = 0 ; /* Create some random data. */ for (k = 0 ; k < BUFFER_LEN ; k++) data [k] = (rand () % 2000) ; if (! (file = sf_open_write ("-", &sfinfo))) { fprintf (stderr, "sf_open_write failed with error : ") ; sf_perror (NULL) ; exit (1) ; } ; total = 0 ; while (total < count) { this_write = (count - total > BUFFER_LEN) ? BUFFER_LEN : count - total ; if ((k = sf_write_short (file, data, this_write)) != this_write) { fprintf (stderr, "sf_write_short # %d failed with short write (%d ->%d)\n", count, this_write, k) ; exit (1) ; } ; total += k ; } ; sf_close (file) ; fprintf (stderr, "ok\n") ; return ; } /* stdout_test */
void combsplit_ok(void) { int i,ch; int div,num; char filename[200]={0},tmpfn[200]={0}; char extension[20]={0}; char *extp; int nch,nchN; GUI_aboveprogressbar(0,samps_per_frame*num); div=combsplit_block_size; num=combsplit_number_of_files; for (i=0; i<samps_per_frame*N; i++) lyd2[i]=lyd[i]; /* rett kanal : (i/div)%num==kanalnr */ for (ch=0; ch<num; ch++) { printf("ch: %d\n",ch); for(nch=0;nch<samps_per_frame;nch++){ nchN=nch*N; for (i=0; i<N/2; i++) { if ( ((i/div)%num)==ch) { lyd[i+i+nchN]=lyd2[i+i+nchN]; lyd[i+i+1+nchN]=lyd2[i+i+1+nchN]; } else { lyd[i+i+nchN]=0.; lyd[i+i+1+nchN]=0.; } } } /*og så må vi lagre da*/ extp=strrchr(playfile,'.'); if(extp>strrchr(playfile,'/')) { strcpy(extension,++extp); strncpy(tmpfn,playfile,(extp-playfile)-1); // tmpfn[extp-playfile-1]=0; sprintf(filename,"%s-%d.%s",tmpfn,ch,extension); }else{ sprintf(filename,"%s-%d",playfile,ch); } /* out_AFsetup=afNewFileSetup(); afInitChannels(out_AFsetup, AF_DEFAULT_TRACK, samps_per_frame); afInitRate(out_AFsetup, AF_DEFAULT_TRACK, R); afInitCompression(out_AFsetup, AF_DEFAULT_TRACK, compression); afInitFileFormat(out_AFsetup, filefmt); afInitSampleFormat(out_AFsetup, AF_DEFAULT_TRACK, samp_type, bits_per_samp); outfile=afOpenFile(filename, "wb", out_AFsetup); */ outfile=sf_open_write(filename,&loadstruct.sfinfo); if (outfile==NULL) { fprintf(stderr,"Could not open file. \"%s\".\n",filename); continue; } for(nch=0;nch<samps_per_frame;nch++){ GUI_aboveprogressbar(ch*samps_per_frame + nch,samps_per_frame*num); nchN=nch*N; rfft(lyd+nchN,N/2,INVERSE); } writesound(SaveWaveConsumer,outfile); // afCloseFile(outfile); sf_close(outfile); } for (i=0; i<samps_per_frame*N; i++) lyd[i]=lyd2[i]; }
void split_real_imag_ok(void) { int i,ch; char filename[200]={0},tmpfn[200]={0}; char extension[20]={0}; char *extp; int nch,nchN; GUI_aboveprogressbar(0,samps_per_frame*2); for (i=0; i<samps_per_frame*N; i++) lyd2[i]=lyd[i]; for (ch=0; ch<2; ch++) { for(nch=0;nch<samps_per_frame;nch++){ nchN=nch*N; for (i=0; i<N/2; i++) { if (ch%2) { lyd[i+i+nchN]=0.; lyd[i+i+1+nchN]=lyd2[i+i+1+nchN]; } else { lyd[i+i+nchN]=lyd2[i+i+nchN]; lyd[i+i+1+nchN]=0.; } } } /*og så må vi lagre da*/ extp=strrchr(playfile,'.'); if(extp>strrchr(playfile,'/')) { strcpy(extension,++extp); strncpy(tmpfn,playfile,(extp-playfile)-1); sprintf(filename,"%s-%d.%s",tmpfn,ch,extension); } else sprintf(filename,"%s-%d",playfile,ch); /* out_AFsetup=afNewFileSetup(); afInitChannels(out_AFsetup, AF_DEFAULT_TRACK, samps_per_frame); afInitRate(out_AFsetup, AF_DEFAULT_TRACK, R); afInitCompression(out_AFsetup, AF_DEFAULT_TRACK, compression); afInitFileFormat(out_AFsetup, filefmt); afInitSampleFormat(out_AFsetup, AF_DEFAULT_TRACK, samp_type, bits_per_samp); outfile=afOpenFile(filename, "wb", out_AFsetup); */ outfile=sf_open_write(filename,&loadstruct.sfinfo); if (outfile==NULL) { fprintf(stderr,"Could not open file \"%s\".\n",filename); continue; } for(nch=0;nch<samps_per_frame;nch++){ GUI_aboveprogressbar(ch*samps_per_frame + nch,samps_per_frame*2); nchN=nch*N; rfft(lyd+nchN,N/2,INVERSE); } writesound(SaveWaveConsumer,outfile); sf_close(outfile); } for (i=0; i<samps_per_frame*N; i++) lyd[i]=lyd2[i]; }
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 */
bool ExportPCM(AudacityProject *project, bool stereo, wxString fName, bool selectionOnly, double t0, double t1) { double rate = project->GetRate(); wxWindow *parent = project; TrackList *tracks = project->GetTracks(); int format = ReadExportFormatPref(); int formatBits = ReadExportFormatBitsPref(); wxString formatStr; SF_INFO info; SNDFILE *sf; int err; formatStr = sf_header_name(format & SF_FORMAT_TYPEMASK); // Use libsndfile to export file info.samplerate = (unsigned int)(rate + 0.5); info.samples = (unsigned int)((t1 - t0)*rate + 0.5); info.channels = stereo? 2: 1; info.pcmbitwidth = formatBits; info.format = format; info.sections = 1; info.seekable = 0; // If we can't export exactly the format they requested, // try the default format for that header type, and try // 16-bit samples. if (!sf_format_check(&info)) info.format = (info.format & SF_FORMAT_TYPEMASK); if (!sf_format_check(&info)) info.pcmbitwidth = 16; if (!sf_format_check(&info)) { wxMessageBox(_("Cannot export audio in this format.")); return false; } sf = sf_open_write((const char *)fName, &info); if (!sf) { wxMessageBox(wxString::Format(_("Cannot export audio to %s"), (const char *)fName)); return false; } double timeStep = 10.0; // write in blocks of 10 secs wxProgressDialog *progress = NULL; wxYield(); wxStartTimer(); wxBusyCursor busy; bool cancelling = false; double t = t0; while (t < t1 && !cancelling) { double deltat = timeStep; if (t + deltat > t1) deltat = t1 - t; sampleCount numSamples = int (deltat * rate + 0.5); Mixer *mixer = new Mixer(stereo ? 2 : 1, numSamples, true, rate); wxASSERT(mixer); mixer->Clear(); TrackListIterator iter(tracks); VTrack *tr = iter.First(); while (tr) { if (tr->GetKind() == VTrack::Wave) { if (tr->GetSelected() || !selectionOnly) { if (tr->GetChannel() == VTrack::MonoChannel) mixer->MixMono((WaveTrack *) tr, t, t + deltat); if (tr->GetChannel() == VTrack::LeftChannel) mixer->MixLeft((WaveTrack *) tr, t, t + deltat); if (tr->GetChannel() == VTrack::RightChannel) mixer->MixRight((WaveTrack *) tr, t, t + deltat); } } tr = iter.Next(); } sampleType *mixed = mixer->GetBuffer(); sf_writef_short(sf, mixed, numSamples); t += deltat; if (!progress && wxGetElapsedTime(false) > 500) { wxString message; if (selectionOnly) message = wxString:: Format(_("Exporting the selected audio as a %s file"), (const char *) formatStr); else message = wxString:: Format(_("Exporting the entire project as a %s file"), (const char *) formatStr); progress = new wxProgressDialog(_("Export"), message, 1000, parent, wxPD_CAN_ABORT | wxPD_REMAINING_TIME | wxPD_AUTO_HIDE); } if (progress) { cancelling = !progress->Update(int (((t - t0) * 1000) / (t1 - t0) + 0.5)); } delete mixer; } err = sf_close(sf); if (err) { char buffer[1000]; sf_error_str(sf, buffer, 1000); wxMessageBox(wxString::Format (_("Error (file may not have been written): %s"), buffer)); } #ifdef __WXMAC__ FSSpec spec; wxMacFilename2FSSpec(fName, &spec); FInfo finfo; if (FSpGetFInfo(&spec, &finfo) == noErr) { finfo.fdType = sf_header_mactype(format & SF_FORMAT_TYPEMASK); finfo.fdCreator = AUDACITY_CREATOR; FSpSetFInfo(&spec, &finfo); } #endif if (progress) delete progress; return true; }