Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}