static UINT ogg_dec(GETSND snd, short *dst) { __OV *ov; int result; char *buffer; int bytes; float **pcm; int samples; int i; int j; float *mono; short *ptr; long val; ov = (__OV *)snd->snd; do { switch(ov->phase) { case OVPHASE_HEAD: result = ogg_sync_pageout(&ov->oy, &ov->og); if (result > 0) { ogg_stream_pagein(&ov->os, &ov->og); ov->phase = OVPHASE_STREAMIN; } else if (result == 0) { ov->phase = OVPHASE_NEXT; } else { TRACEOUT(("Corrupt or missing data in bitstream")); } break; case OVPHASE_STREAMIN: result = ogg_stream_packetout(&ov->os, &ov->op); if (result > 0) { if (vorbis_synthesis(&ov->vb, &ov->op) == 0) { vorbis_synthesis_blockin(&ov->vd, &ov->vb); } ov->phase = OVPHASE_GETPCM; } else if (result == 0) { if (!ogg_page_eos(&ov->og)) { ov->phase = OVPHASE_NEXT; } else { ov->phase = OVPHASE_CLOSE; } } break; case OVPHASE_GETPCM: samples = vorbis_synthesis_pcmout(&ov->vd, &pcm); if (samples > 0) { if (samples > (int)snd->blocksamples) { samples = (int)snd->blocksamples; } for (i=0; i<ov->vi.channels; i++) { ptr = dst + i; mono = pcm[i]; for (j=0; j<samples; j++) { val = (long)(mono[j] * 32767.f); if (val > 32767) { val = 32767; } if (val < -32768) { val = -32768; } *ptr = (short)val; ptr += ov->vi.channels; } } vorbis_synthesis_read(&ov->vd, samples); return((UINT)samples); } ov->phase = OVPHASE_STREAMIN; break; case OVPHASE_NEXT: buffer = ogg_sync_buffer(&ov->oy, 4096); bytes = snd_read(snd, buffer, 4096); ogg_sync_wrote(&ov->oy, bytes); #if 1 ov->phase = OVPHASE_HEAD; #else if (bytes) { ov->phase = OVPHASE_HEAD; } else { ov->phase = OVPHASE_CLOSE; } #endif break; case OVPHASE_CLOSE: return(0); } } while(1); }
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 getogg_open(GETSND snd, UINT8 *ptr, UINT size) { __OV *ov; char *buffer; int bytes; int i; int result; snd->datptr = ptr; snd->datsize = size; ov = (__OV *)_MALLOC(sizeof(__OV), "__OV"); if (ov == NULL) { goto ovopn_err0; } ZeroMemory(ov, sizeof(__OV)); buffer = ogg_sync_buffer(&ov->oy, 4096); bytes = snd_read(snd, buffer, 4096); ogg_sync_wrote(&ov->oy, bytes); if (ogg_sync_pageout(&ov->oy, &ov->og) != 1) { TRACEOUT(("Input does not appear to be an Ogg bitstream.")); goto ovopn_err1; } ogg_stream_init(&ov->os, ogg_page_serialno(&ov->og)); vorbis_info_init(&ov->vi); vorbis_comment_init(&ov->vc); if (ogg_stream_pagein(&ov->os, &ov->og) < 0) { TRACEOUT(("Error reading first page of Ogg bitstream data.")); goto ovopn_err1; } if (ogg_stream_packetout(&ov->os, &ov->op) != 1) { TRACEOUT(("Error reading initial header packet.")); goto ovopn_err1; } if (vorbis_synthesis_headerin(&ov->vi, &ov->vc, &ov->op) < 0) { TRACEOUT(("This Ogg bitstream does not contain Vorbis audio data.")); goto ovopn_err1; } i = 0; while(i < 2) { while(i < 2) { result = ogg_sync_pageout(&ov->oy, &ov->og); if (result == 0) { break; } if (result == 1) { ogg_stream_pagein(&ov->os, &ov->og); while(i < 2) { result = ogg_stream_packetout(&ov->os, &ov->op); if (result == 0) { break; } if (result < 0) { TRACEOUT(("Corrupt secondary header. Exiting.")); goto ovopn_err1; } vorbis_synthesis_headerin(&ov->vi, &ov->vc, &ov->op); i++; } } } buffer = ogg_sync_buffer(&ov->oy, 4096); bytes = snd_read(snd, buffer, 4096); if ((bytes == 0) && (i < 2)) { TRACEOUT(("End of file before finding all Vorbis headers!")); return(-1); } ogg_sync_wrote(&ov->oy, bytes); } snd->snd = ov; snd->dec = (GSDEC)ogg_dec; snd->decend = ogg_decend; snd->samplingrate = ov->vi.rate; snd->channels = ov->vi.channels; snd->blocksize = 4096 * 2; snd->blocksamples = 4096 / ov->vi.channels; snd->bit = 16; vorbis_synthesis_init(&ov->vd, &ov->vi); vorbis_block_init(&ov->vd, &ov->vb); return(SUCCESS); ovopn_err1: ogg_sync_clear(&ov->oy); _MFREE(ov); ovopn_err0: return(FAILURE); }
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); }