bool ImportWAV(wxString fName, WaveTrack **dest1, WaveTrack **dest2, DirManager *dirManager) { *dest1 = 0; *dest2 = 0; snd_node sndfile; snd_node sndbuffer; sndfile.device = SND_DEVICE_FILE; sndfile.write_flag = SND_READ; strcpy(sndfile.u.file.filename, (const char *)fName); sndfile.u.file.file = 0; int err; long flags=0; err = snd_open(&sndfile, &flags); if (err) return false; if (sndfile.format.channels < 1 || sndfile.format.channels > 2) { wxMessageBox("Unknown audio format."); return false; } *dest1 = new WaveTrack(dirManager); wxASSERT(*dest1); (*dest1)->rate = sndfile.format.srate; if (sndfile.format.channels == 2) { *dest2 = new WaveTrack(dirManager); wxASSERT(*dest1); (*dest2)->rate = sndfile.format.srate; } sndbuffer.device = SND_DEVICE_MEM; sndbuffer.write_flag = SND_WRITE; sndbuffer.u.mem.buffer_max = 0; sndbuffer.u.mem.buffer = 0; sndbuffer.u.mem.buffer_len = 0; sndbuffer.u.mem.buffer_pos = 0; sndbuffer.format.channels = sndfile.format.channels; sndbuffer.format.mode = SND_MODE_PCM; // SND_MODE_FLOAT sndbuffer.format.bits = 16; sndbuffer.format.srate = sndfile.format.srate; int maxblocksize = WaveTrack::GetIdealBlockSize(); char *srcbuffer = new char[maxblocksize*2]; char *dstbuffer = new char[maxblocksize*2]; char *leftbuffer = new char[maxblocksize*2]; char *rightbuffer = new char[maxblocksize*2]; long filelen = sndfile.u.file.end_offset - sndfile.u.file.byte_offset; long bytescompleted = 0; wxProgressDialog *progress = NULL; wxYield(); wxStartTimer(); wxBusyCursor busy; long block; do { block = maxblocksize; block = snd_read(&sndfile, srcbuffer, block); if (block > 0) { long b2 = snd_convert(&sndbuffer, dstbuffer, // to &sndfile, srcbuffer, block); // from if (sndfile.format.channels == 1) (*dest1)->Append((sampleType *)dstbuffer, b2); else { for(int i=0; i<b2; i++) { ((sampleType *)leftbuffer)[i] = ((sampleType *)dstbuffer)[2*i]; ((sampleType *)rightbuffer)[i] = ((sampleType *)dstbuffer)[2*i+1]; } (*dest1)->Append((sampleType *)leftbuffer, (sampleCount)b2); (*dest2)->Append((sampleType *)rightbuffer, (sampleCount)b2); } bytescompleted += block; } if (!progress && wxGetElapsedTime(false) > 500) { progress = new wxProgressDialog("Import","Importing audio file", filelen); } if (progress) { int progressvalue = (bytescompleted > filelen)? filelen : bytescompleted; progress->Update(progressvalue); } } while (block > 0); snd_close(&sndfile); #ifndef __WXMAC__ if (bytescompleted != filelen) { printf("Bytes completed: %d Expected file len: %d\n", bytescompleted, filelen); } #endif if (progress) delete progress; delete[] srcbuffer; delete[] dstbuffer; delete[] leftbuffer; delete[] rightbuffer; return true; }
bool ExportPCM(AudacityProject *project, wxString format, bool stereo, wxString fName, bool selectionOnly, double t0, double t1) { wxMessageBox("In process of being rewritten, sorry..."); #if 0 double rate = project->GetRate(); wxWindow *parent = project; TrackList *tracks = project->GetTracks(); int header = SND_HEAD_NONE; #ifdef __WXMAC__ bool trackMarkers = false; #endif if (format == "WAV") header = SND_HEAD_WAVE; else if (format == "AIFF") header = SND_HEAD_AIFF; else if (format == "IRCAM") header = SND_HEAD_IRCAM; else if (format == "AU") header = SND_HEAD_NEXT; #ifdef __WXMAC__ else if (format == "AIFF with track markers") { header = SND_HEAD_AIFF; trackMarkers = true; } #endif // Use snd library to export file snd_node sndfile; snd_node sndbuffer; sndfile.device = SND_DEVICE_FILE; sndfile.write_flag = SND_WRITE; strcpy(sndfile.u.file.filename, (const char *) fName); sndfile.u.file.file = 0; sndfile.u.file.header = header; sndfile.u.file.byte_offset = 0; sndfile.u.file.end_offset = 0; sndfile.u.file.swap = 0; sndfile.format.channels = stereo ? 2 : 1; sndfile.format.mode = SND_MODE_PCM; // SND_MODE_FLOAT sndfile.format.bits = 16; sndfile.format.srate = int (rate + 0.5); int err; long flags = 0; err = snd_open(&sndfile, &flags); if (err) { wxMessageBox("Could not write to file."); return false; } sndbuffer.device = SND_DEVICE_MEM; sndbuffer.write_flag = SND_READ; sndbuffer.u.mem.buffer_max = 0; sndbuffer.u.mem.buffer = 0; sndbuffer.u.mem.buffer_len = 0; sndbuffer.u.mem.buffer_pos = 0; sndbuffer.format.channels = stereo ? 2 : 1; sndbuffer.format.mode = SND_MODE_PCM; // SND_MODE_FLOAT sndbuffer.format.bits = 16; sndbuffer.format.srate = int (rate + 0.5); 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(); char *buffer = new char[numSamples * 2 * sndbuffer.format.channels]; wxASSERT(buffer); TrackListIterator iter(tracks); VTrack *tr = iter.First(); while (tr) { if (tr->GetKind() == VTrack::Wave) { if (tr->selected || !selectionOnly) { if (tr->channel == VTrack::MonoChannel) mixer->MixMono((WaveTrack *) tr, t, t + deltat); if (tr->channel == VTrack::LeftChannel) mixer->MixLeft((WaveTrack *) tr, t, t + deltat); if (tr->channel == VTrack::RightChannel) mixer->MixRight((WaveTrack *) tr, t, t + deltat); } } tr = iter.Next(); } sampleType *mixed = mixer->GetBuffer(); long b2 = snd_convert(&sndfile, buffer, // to &sndbuffer, mixed, numSamples); // from snd_write(&sndfile, buffer, b2); t += deltat; if (!progress && wxGetElapsedTime(false) > 500) { wxString message; if (selectionOnly) message = wxString:: Format("Exporting the selected audio as a %s file", (const char *) format); else message = wxString:: Format("Exporting the entire project as a %s file", (const char *) format); 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; delete[]buffer; } snd_close(&sndfile); #ifdef __WXMAC__ FSSpec spec; wxMacFilename2FSSpec(fName, &spec); if (trackMarkers) { // Export the label track as "CD Spin Doctor" files LabelTrack *labels = NULL; TrackListIterator iter(tracks); VTrack *t = iter.First(); while (t && !labels) { if (t->GetKind() == VTrack::Label) labels = (LabelTrack *) t; t = iter.Next(); } if (labels) { FSpCreateResFile(&spec, 'AIFF', AUDACITY_CREATOR, 0); int resFile = FSpOpenResFile(&spec, fsWrPerm); if (resFile == -1) { int x = ResError(); } if (resFile != -1) { UseResFile(resFile); int numLabels = labels->mLabels.Count(); for (int i = 0; i < numLabels; i++) { int startBlock = (int) (labels->mLabels[i]->t * 75); int lenBlock; if (i < numLabels - 1) lenBlock = (int) ((labels->mLabels[i + 1]->t - labels->mLabels[i]->t) * 75); else lenBlock = (int) ((tracks->GetMaxLen() - labels->mLabels[i]->t) * 75); int startSample = startBlock * 1176 + 54; int lenSample = lenBlock * 1176 + 54; Handle theHandle = NewHandle(50); HLock(theHandle); char *data = (char *) (*theHandle); *(int *) &data[0] = startSample; *(int *) &data[4] = lenSample; *(int *) &data[8] = startBlock; *(int *) &data[12] = lenBlock; *(short *) &data[16] = i + 1; wxString title = labels->mLabels[i]->title; if (title.Length() > 31) title = title.Left(31); data[18] = title.Length(); strcpy(&data[19], (const char *) title); HUnlock(theHandle); AddResource(theHandle, 'SdCv', 128 + i, "\p"); } CloseResFile(resFile); wxMessageBox("Saved track information with file."); } } } FInfo finfo; if (FSpGetFInfo(&spec, &finfo) == noErr) { switch (header) { case SND_HEAD_AIFF: finfo.fdType = 'AIFF'; break; case SND_HEAD_IRCAM: finfo.fdType = 'IRCA'; break; case SND_HEAD_NEXT: finfo.fdType = 'AU '; break; case SND_HEAD_WAVE: finfo.fdType = 'WAVE'; break; } finfo.fdCreator = AUDACITY_CREATOR; FSpSetFInfo(&spec, &finfo); } #endif if (progress) delete progress; return true; #endif return false; }
int main(int argc, char *argv[]) { char *fromfile = NULL; char *tofile = NULL; int i; long flags = 0; long frames; long len; long checksum = 0; long count = 0; int format = SND_HEAD_AIFF; int mode = SND_MODE_PCM; int channels = 1; int bits = 16; double srate = 44100.0; snd_node from_snd, to_snd; char from_buf[MAXLEN]; char to_buf[MAXLEN]; long frames_from_len; long frames_to_len; long from_len = 0; long to_len = 0; for (i = 1; i < argc; i++) { if (*(argv[i]) != '-') { if (!fromfile) fromfile = argv[i]; else if (!tofile) tofile = argv[i]; else { printf("%s: don't know what to do with 3rd file\n", argv[i]); return 1; } } else { char *flag = argv[i] + 1; if (*flag == '?') { printf("convert -- sound file conversion utility\n\n"); printf("usage: convert fromfile tofile -flag1 -flag2 ...\n"); printf(" -fa -- AIFF file format\n"); printf(" -fi -- IRCAM file format\n"); printf(" -fn -- NeXT/Sun file format\n"); printf(" -fw -- Wave file format\n"); printf(" -ep -- PCM\n"); printf(" -em -- u-Law\n"); printf(" -ef -- float\n"); printf(" -eu -- unsigned PCM\n"); printf(" -b1 -- 8-bit\n"); printf(" -b2 -- 16-bit\n"); printf(" -b4 -- 32-bit\n"); printf(" -c1 -- 1 channel, etc.\n"); printf("use 'ada' to get audio input or output\n"); } else if (*flag == 'f') { switch (flag[1]) { case 'a': format = SND_HEAD_AIFF; break; case 'i': format = SND_HEAD_IRCAM; break; case 'n': format = SND_HEAD_NEXT; break; case 'w': format = SND_HEAD_WAVE; break; default: printf("flag %s ignored\n", argv[i]); break; } } else if (*flag == 'e') { switch (flag[1]) { case 'p': mode = SND_MODE_PCM; break; case 'm': mode = SND_MODE_ULAW; break; case 'f': mode = SND_MODE_FLOAT; break; case 'u': mode = SND_MODE_UPCM; break; default: printf("flag %s ignored\n", argv[i]); break; } } else if (*flag == 'b') { switch (flag[1]) { case '1': bits = 8; break; case '2': bits = 16; break; case '4': bits = 32; break; default: printf("flag %s ignored\n", argv[i]); break; } } else if (*flag == 'r') { switch (flag[1]) { case '4': srate = 44100.0; break; case '2': srate = 22050.0; break; case '1': srate = 11025.0; break; case '8': srate = 8000.0; break; default: printf("flag %s ignored\n", argv[i]); break; } } else if (*flag == 'c') { channels = atoi(flag+1); if (channels < 1 || channels > 16) { channels = 1; printf("flag %s ignored, using 1 channel\n", argv[i]); } } } } if (!tofile) { printf("2 files not found, use -? for help\n"); return 1; } from_snd.device = SND_DEVICE_FILE; from_snd.write_flag = SND_READ; from_snd.u.file.byte_offset = 0; from_snd.format.channels = channels; from_snd.format.mode = mode; from_snd.format.bits = bits; from_snd.format.srate = srate; if (strcmp(fromfile, "ada") == 0) { from_snd.device = SND_DEVICE_AUDIO; from_snd.u.audio.protocol = SND_COMPUTEAHEAD; from_snd.u.audio.latency = 1.0; from_snd.u.audio.granularity = 0.1; strcpy(from_snd.u.file.filename, ""); } else { strcpy(from_snd.u.file.filename, fromfile); } if (snd_open(&from_snd, &flags) != SND_SUCCESS) { printf("error opening %s for input\n", fromfile); exit(1); } printf("Opened %s for input: ", from_snd.u.file.filename); snd_print_info(&from_snd); to_snd.device = SND_DEVICE_FILE; to_snd.write_flag = SND_WRITE; to_snd.format.channels = channels; to_snd.format.mode = mode; to_snd.format.bits = bits; to_snd.format.srate = from_snd.format.srate; to_snd.u.file.header = format; /* header format, e.g. AIFF */ if (to_snd.u.file.header == SND_HEAD_WAVE && to_snd.format.mode == SND_MODE_PCM && to_snd.format.bits == 8) to_snd.format.mode = SND_MODE_UPCM; if (strcmp(tofile, "ada") == 0) { to_snd.device = SND_DEVICE_AUDIO; to_snd.u.audio.protocol = SND_COMPUTEAHEAD; to_snd.u.audio.latency = 0.0; to_snd.u.audio.granularity = 0.1; strcpy(to_snd.u.audio.interfacename, ""); strcpy(to_snd.u.audio.devicename, ""); } else { strcpy(to_snd.u.file.filename, tofile); } if (snd_open(&to_snd, &flags) != SND_SUCCESS) { printf("error opening %s for output\n", tofile); exit(1); } printf("Opened %s for output: ", to_snd.u.file.filename); snd_print_info(&to_snd); /* figure out how much to convert on each iteration */ /* first, compute how many frames could fit in each buffer */ from_len = MAXLEN / snd_bytes_per_frame(&from_snd); to_len = MAXLEN / snd_bytes_per_frame(&to_snd); /* then compute the minimum of the two frame counts */ frames = min(from_len, to_len); while (1) { /* then convert back from frame counts to byte counts: */ while ((frames_from_len = snd_poll(&from_snd)) <=0); frames_from_len = min(frames_from_len, frames); while ((frames_to_len = snd_poll(&to_snd)) <= 0); frames_to_len = min(frames_to_len, frames); len = min(frames_to_len, frames_from_len); len = snd_read(&from_snd, from_buf, len); if (((from_snd.device == SND_DEVICE_AUDIO) && (count > from_snd.format.srate * 10)) || (!len)) { break; } for (i = 0; i < len * snd_bytes_per_frame(&from_snd); i++) { checksum += from_buf[i]; count++; } len = snd_convert(&to_snd, to_buf, &from_snd, from_buf, len); len = snd_write(&to_snd, to_buf, len); printf("#"); fflush(stdout); } snd_close(&from_snd); if (to_snd.device == SND_DEVICE_AUDIO) { while (snd_flush(&to_snd) != SND_SUCCESS) ; } snd_close(&to_snd); printf("Read %ld frames, checksum = %ld\n", count, checksum); exit(0); }