Esempio n. 1
0
int TrackCount(const char* strFile)
{
  VorbisContext* ctx = new VorbisContext;
  ctx->file = XBMC->OpenFile(strFile, 4);
  if (!ctx->file)
  {
    delete ctx;
    return 1;
  }
  ctx->callbacks = GetCallbacks(strFile);

  if (ov_open_callbacks(ctx->file, &ctx->vorbisfile,
                        NULL, 0, ctx->callbacks) != 0)
  {
    delete ctx;
    return 1;
  }

  long iStreams=ov_streams(&ctx->vorbisfile);

  ov_clear(&ctx->vorbisfile);
  delete ctx;

  return iStreams;
}
Esempio n. 2
0
int main(){
  OggVorbis_File ov;
  int i;

#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  /* Beware the evil ifdef. We avoid these where we can, but this one we 
     cannot. Don't add any more, you'll probably go to hell if you do. */
  _setmode( _fileno( stdin ), _O_BINARY );
  _setmode( _fileno( stdout ), _O_BINARY );
#endif

  /* open the file/pipe on stdin */
  if(ov_open(stdin,&ov,NULL,-1)<0){
    printf("Could not open input as an OggVorbis file.\n\n");
    exit(1);
  }
  
  /* print details about each logical bitstream in the input */
  if(ov_seekable(&ov)){
    printf("Input bitstream contained %ld logical bitstream section(s).\n",
	   ov_streams(&ov));
    printf("Total bitstream samples: %ld\n\n",
	   (long)ov_pcm_total(&ov,-1));
    printf("Total bitstream playing time: %ld seconds\n\n",
	   (long)ov_time_total(&ov,-1));

  }else{
    printf("Standard input was not seekable.\n"
	   "First logical bitstream information:\n\n");
  }

  for(i=0;i<ov_streams(&ov);i++){
    vorbis_info *vi=ov_info(&ov,i);
    printf("\tlogical bitstream section %d information:\n",i+1);
    printf("\t\t%ldHz %d channels bitrate %ldkbps serial number=%ld\n",
	   vi->rate,vi->channels,ov_bitrate(&ov,i)/1000,
	   ov_serialnumber(&ov,i));
    printf("\t\theader length: %ld bytes\n",(long)
	   (ov.dataoffsets[i]-ov.offsets[i]));
    printf("\t\tcompressed length: %ld bytes\n",(long)(ov_raw_total(&ov,i)));
    printf("\t\tplay time: %lds\n",(long)ov_time_total(&ov,i));
  }

  ov_clear(&ov);
  return 0;
}
Esempio n. 3
0
static qboolean S_VORBIS_CodecOpenStream (snd_stream_t *stream)
{
	OggVorbis_File *ovFile;
	vorbis_info *ovf_info;
	long numstreams;
	int res;

	ovFile = (OggVorbis_File *) Z_Malloc(sizeof(OggVorbis_File), Z_MAINZONE);
	stream->priv = ovFile;
	res = ov_open_callbacks(&stream->fh, ovFile, NULL, 0, ovc_qfs);
	if (res != 0)
	{
		Con_Printf("%s is not a valid Ogg Vorbis file (error %i).\n",
				stream->name, res);
		goto _fail;
	}

	if (!ov_seekable(ovFile))
	{
		Con_Printf("Stream %s not seekable.\n", stream->name);
		goto _fail;
	}

	ovf_info = ov_info(ovFile, 0);
	if (!ovf_info)
	{
		Con_Printf("Unable to get stream info for %s.\n", stream->name);
		goto _fail;
	}

	/* FIXME: handle section changes */
	numstreams = ov_streams(ovFile);
	if (numstreams != 1)
	{
		Con_Printf("More than one (%ld) stream in %s.\n",
					numstreams, stream->name);
		goto _fail;
	}

	if (ovf_info->channels != 1 && ovf_info->channels != 2)
	{
		Con_Printf("Unsupported number of channels %d in %s\n",
					ovf_info->channels, stream->name);
		goto _fail;
	}

	stream->info.rate = ovf_info->rate;
	stream->info.channels = ovf_info->channels;
	stream->info.bits = VORBIS_SAMPLEBITS;
	stream->info.width = VORBIS_SAMPLEWIDTH;

	return true;
_fail:
	if (res == 0)
		ov_clear(ovFile);
	Z_Free(ovFile);
	return false;
}
Esempio n. 4
0
AudioData LoadOggCodec(std::string filename)
{
	std::string audioFile;
	try
	{
		audioFile = FS::PakPath::ReadFile(filename);
	}
	catch (std::system_error& err)
	{
		audioLogs.Warn("Failed to open %s: %s", filename, err.what());
		return AudioData();
	}
	OggDataSource dataSource = {&audioFile, 0};
	std::unique_ptr<OggVorbis_File> vorbisFile(new OggVorbis_File);

	if (ov_open_callbacks(&dataSource, vorbisFile.get(), nullptr, 0, Ogg_Callbacks) != 0) {
        audioLogs.Warn("Error while reading %s", filename);
		ov_clear(vorbisFile.get());
		return AudioData();
	}

	if (ov_streams(vorbisFile.get()) != 1) {
		audioLogs.Warn("Unsupported number of streams in %s.", filename);
		ov_clear(vorbisFile.get());
		return AudioData();
	}

	vorbis_info* oggInfo = ov_info(vorbisFile.get(), 0);

	if (!oggInfo) {
        audioLogs.Warn("Could not read vorbis_info in %s.", filename);
		ov_clear(vorbisFile.get());
		return AudioData();
	}

	const int sampleWidth = 2;

	int sampleRate = oggInfo->rate;
	int numberOfChannels = oggInfo->channels;

	char buffer[4096];
	int bytesRead = 0;
	int bitStream = 0;

	std::vector<char> samples;

	while ((bytesRead = ov_read(vorbisFile.get(), buffer, 4096, 0, sampleWidth, 1, &bitStream)) > 0) {
		std::copy_n(buffer, bytesRead, std::back_inserter(samples));
	}
	ov_clear(vorbisFile.get());

	char* rawSamples = new char[samples.size()];
	std::copy_n(samples.data(), samples.size(), rawSamples);
	return AudioData(sampleRate, sampleWidth, numberOfChannels, samples.size(), rawSamples);
}
Esempio n. 5
0
 void setup()
 {
     static const ov_callbacks cbs = { readCallback, 0, 0, 0 };
     ov_open_callbacks(this, &file_, 0, 0, cbs);
     
     vorbis_info* info = ov_info(&file_, -1); // -1 is current bitstream
     if (ov_streams(&file_) != 1)
         throw std::runtime_error("multi-stream vorbis files not supported");
     
     format_ = info->channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
     sampleRate_ = info->rate;
 }
Esempio n. 6
0
bool OggFilter::Attach(IFS* src)
{
	if(!ov_open_callbacks((void*)src, &Vorbis, NULL, 0, Callbacks) && (ov_streams(&Vorbis) == 1))
	{
		Source = src;

		vorbis_info* info = ov_info(&Vorbis, -1);

		Wave.Format.Channels = info->channels;
		Wave.Format.SamplesPerSec = info->rate;
		Wave.Format.BlockAlign = Wave.Format.Channels * Wave.Format.BitsPerSample / 8;
		Wave.Format.AvgBytesPerSec = Wave.Format.SamplesPerSec * Wave.Format.BlockAlign;
		Wave.dataChunk.ChunkSize = (uInt)ov_pcm_total(&Vorbis, -1) * Wave.Format.BlockAlign;
		Wave.Header.RiffSize = Wave.dataChunk.ChunkSize + sizeof(WaveFile) - 8;

		Offset = 0;
		return true;
	}
	Close();
	return false;
}
Esempio n. 7
0
int
vorbis_decoder_finish_open(decoder_t * dec) {

	vorbis_pdata_t * pd = (vorbis_pdata_t *)dec->pdata;
	file_decoder_t * fdec = dec->fdec;

	pd->vi = ov_info(&(pd->vf), -1);
	if ((pd->vi->channels != 1) && (pd->vi->channels != 2)) {
		fprintf(stderr,
			"vorbis_decoder_open: Ogg Vorbis file with %d channels "
			"is unsupported\n", pd->vi->channels);
		return DECODER_OPEN_FERROR;
	}
	if (ov_streams(&(pd->vf)) != 1) {
		fprintf(stderr,
			"vorbis_decoder_open: This Ogg Vorbis file contains "
			"multiple logical streams.\n"
			"Currently such a file is not supported.\n");
		return DECODER_OPEN_FERROR;
	}

	pd->is_eos = 0;
	pd->rb = rb_create(pd->vi->channels * sample_size * RB_VORBIS_SIZE);
	fdec->fileinfo.channels = pd->vi->channels;
	fdec->fileinfo.sample_rate = pd->vi->rate;
	if (fdec->is_stream && pd->session->type != HTTPC_SESSION_NORMAL) {
		fdec->fileinfo.total_samples = 0;
	} else {
		fdec->fileinfo.total_samples = ov_pcm_total(&(pd->vf), -1);
	}
	fdec->fileinfo.bps = ov_bitrate(&(pd->vf), -1);

	fdec->file_lib = VORBIS_LIB;
	strcpy(dec->format_str, "Ogg Vorbis");

	vorbis_send_metadata(fdec, pd);
	vorbis_decoder_send_metadata(dec);

	return DECODER_OPEN_SUCCESS;
}
Esempio n. 8
0
    /* open ogg/vorbis file */                 
static void oggread_open(t_oggread *x, t_symbol *filename)
{
	int i;

	x->x_stream = 0;
		/* first close previous file */
	if(x->x_fd > 0)
	{
		ov_clear(&x->x_ov);
		post("oggread~: previous file closed");
	}
		/* open file for reading */
    if((x->x_file = sys_fopen(filename->s_name, "rb")) <= 0)
    {
		post("oggread~: could not open file \"%s\"", filename->s_name);
		x->x_eos = 1;
		x->x_fd = -1;
    }
    else
    {
		x->x_stream = 0;
		x->x_eos = 0;
		x->x_fd = 1;
		x->x_outreadposition = 0;
		x->x_outwriteposition = 0;
		x->x_outunread = 0;
		post("oggread~: file \"%s\" opened", filename->s_name);
		outlet_float( x->x_out_position, 0);

			/* try to open as ogg vorbis file */
		if(ov_open(x->x_file, &x->x_ov, NULL, -1) < 0)
		{		/* an error occured (no ogg vorbis file ?) */
			post("oggread~: error: could not open \"%s\" as an OggVorbis file", filename->s_name);
			ov_clear(&x->x_ov);
			post("oggread~: file closed due to error");
      x->x_fd=-1;
      x->x_eos=1;
      return;
		}

			/* print details about each logical bitstream in the input */
		if(ov_seekable(&x->x_ov))
		{
			post("oggread~: input bitstream contained %ld logical bitstream section(s)", ov_streams(&x->x_ov));
			post("oggread~: total bitstream playing time: %ld seconds", (long)ov_time_total(&x->x_ov,-1));
			post("oggread~: encoded by: %s\n",ov_comment(&x->x_ov,-1)->vendor);
		}
		else
		{
			post("oggread~: file \"%s\" was not seekable\n"
			"oggread~: first logical bitstream information:", filename->s_name);
		}

		for(i = 0; i < ov_streams(&x->x_ov); i++)
		{
			x->x_vi = ov_info(&x->x_ov,i);
			post("\tlogical bitstream section %d information:",i+1);
			post("\t\t%ldHz %d channels bitrate %ldkbps serial number=%ld",
				x->x_vi->rate,x->x_vi->channels,ov_bitrate(&x->x_ov,i)/1000, ov_serialnumber(&x->x_ov,i));
			post("\t\theader length: %ld bytes",(long)
			(x->x_ov.dataoffsets[i] - x->x_ov.offsets[i]));
			post("\t\tcompressed length: %ld bytes",(long)(ov_raw_total(&x->x_ov,i)));
			post("\t\tplay time: %ld seconds\n",(long)ov_time_total(&x->x_ov,i));
		}

    } 
}
Esempio n. 9
0
void* Init(const char* strFile, unsigned int filecache, int* channels,
           int* samplerate, int* bitspersample, int64_t* totaltime,
           int* bitrate, AEDataFormat* format, const AEChannel** channelinfo)
{
  VorbisContext* result = new VorbisContext;
  result->track=0;
  std::string toLoad(strFile);
  if (toLoad.find(".oggstream") != std::string::npos)
  {
    size_t iStart=toLoad.rfind('-') + 1;
    result->track = atoi(toLoad.substr(iStart, toLoad.size()-iStart-10).c_str());
    //  The directory we are in, is the file
    //  that contains the bitstream to play,
    //  so extract it
    size_t slash = toLoad.rfind('\\');
    if (slash == std::string::npos)
      slash = toLoad.rfind('/');
    toLoad = toLoad.substr(0, slash);
  }

  result->file = XBMC->OpenFile(toLoad.c_str(), 0);
  if (!result->file)
  {
    delete result;
    return NULL;
  }
  result->callbacks = GetCallbacks(strFile);

  if (ov_open_callbacks(result->file, &result->vorbisfile,
                         NULL, 0, result->callbacks) != 0)
  {
    delete result;
    return NULL;
  }

  long iStreams=ov_streams(&result->vorbisfile);
  if (iStreams>1)
  {
    if (result->track > iStreams)
    {
      DeInit(result);
      return NULL;
    }
  }

  //  Calculate the offset in secs where the bitstream starts
  result->timeoffset = 0;
  for (int i=0; i<result->track; ++i)
    result->timeoffset += ov_time_total(&result->vorbisfile, i);

  vorbis_info* pInfo=ov_info(&result->vorbisfile, result->track);
  if (!pInfo)
  {
    XBMC->Log(ADDON::LOG_ERROR, "OGGCodec: Can't get stream info from %s", toLoad.c_str());
    DeInit(result);
    return NULL;
  }

  *channels      = pInfo->channels;
  *samplerate    = pInfo->rate;
  *bitspersample = 16;
  *totaltime     = (int64_t)ov_time_total(&result->vorbisfile, result->track)*1000;
  *format        = AE_FMT_S16NE;
  static enum AEChannel map[8][9] = {
    {AE_CH_FC, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_LFE, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_SL, AE_CH_SR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
    {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_SL, AE_CH_SR, AE_CH_BL, AE_CH_BR, AE_CH_LFE, AE_CH_NULL}
  };

  *channelinfo = NULL;
  if (*channels <= 8)
    *channelinfo = map[*channels - 1];
  *bitrate = pInfo->bitrate_nominal;

  if (*samplerate == 0 || *channels == 0 || *bitspersample == 0 || *totaltime == 0)
  {
    XBMC->Log(ADDON::LOG_ERROR, "OGGCodec: Can't get stream info, SampleRate=%i, Channels=%i, BitsPerSample=%i, TotalTime=%" PRIu64, *samplerate, *channels, *bitspersample, *totaltime);
    delete result;
    return NULL;
  }

  if (result->timeoffset > 0.0)
  {
    if (ov_time_seek(&result->vorbisfile, result->timeoffset)!=0)
    {
      XBMC->Log(ADDON::LOG_ERROR, "OGGCodec: Can't seek to the bitstream start time (%s)", toLoad.c_str());
      DeInit(result);
      return NULL;
    }
  }

  return result;
}
Esempio n. 10
0
// Open
BOOL WaveFile::Open(LPSTR pszFilename)
{
	int done = FALSE, rc = 0;
	WORD cbExtra = 0;
	BOOL fRtn = SUCCESS;    // assume success
	PCMWAVEFORMAT pcmwf;
	char fullpath[_MAX_PATH];

	m_total_uncompressed_bytes_read = 0;
	m_max_uncompressed_bytes_to_read = AS_HIGHEST_MAX;

	int FileSize, FileOffset;

	if (!cf_find_file_location(pszFilename, CF_TYPE_ANY, sizeof(fullpath) - 1, fullpath, &FileSize, &FileOffset))
	{
		goto OPEN_ERROR;
	}

	m_snd_info.cfp = mmioOpen(fullpath, NULL, MMIO_ALLOCBUF | MMIO_READ);

	if (m_snd_info.cfp == NULL)
	{
		goto OPEN_ERROR;
	}

	m_snd_info.true_offset = FileOffset;
	m_snd_info.size = FileSize;

	// if in a VP then position the stream at the start of the file
	if (FileOffset > 0)
	{
		mmioSeek(m_snd_info.cfp, FileOffset, SEEK_SET);
	}

	// first check for an OGG
	if ((rc = ov_open_callbacks(&m_snd_info, &m_snd_info.vorbis_file, NULL, 0, mmio_callbacks)) == 0)
	{
		// got an OGG so lets read the info in
		ov_info(&m_snd_info.vorbis_file, -1);

		// we only support one logical bitstream
		if (ov_streams(&m_snd_info.vorbis_file) != 1)
		{
			mprintf(("AUDIOSTR => OGG reading error:  We don't handle bitstream changes!\n"));
			goto OPEN_ERROR;
		}

		m_wave_format = OGG_FORMAT_VORBIS;
		m_wfmt.wFormatTag = WAVE_FORMAT_PCM;
		m_wfmt.nChannels = (WORD)m_snd_info.vorbis_file.vi->channels;
		m_wfmt.nSamplesPerSec = m_snd_info.vorbis_file.vi->rate;
		m_wfmt.cbSize = 0;

		if (UserSampleBits == 16 || UserSampleBits == 8)
			m_wfmt.wBitsPerSample = UserSampleBits;				//Decode at whatever the user specifies; only 16 and 8 are supported.
		else if (UserSampleBits > 16)
			m_wfmt.wBitsPerSample = 16;
		else
			m_wfmt.wBitsPerSample = 8;

		m_wfmt.nBlockAlign = (ushort)((m_wfmt.nChannels * m_wfmt.wBitsPerSample) / 8);
		m_wfmt.nAvgBytesPerSec = m_wfmt.nSamplesPerSec * m_wfmt.nBlockAlign;

		m_nBlockAlign = m_wfmt.nBlockAlign;
		m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec;

		// location of start of file in VP
		m_data_offset = 0;
		m_nDataSize = m_data_bytes_left = ((int)ov_pcm_total(&m_snd_info.vorbis_file, -1) * m_wfmt.nBlockAlign);

		// Cue for streaming
		Cue();

		// successful open
		goto OPEN_DONE;
	}
		// not an OGG so assume that it's WAVE
	else
	{

		// extra check, if it's not ogg then but if the error was a bad ogg then bail

		if (rc && (rc != OV_ENOTVORBIS))

			goto OPEN_ERROR;


		// Skip the "RIFF" tag and file size (8 bytes)
		// Skip the "WAVE" tag (4 bytes)
		mmioSeek(m_snd_info.cfp, 12 + FileOffset, SEEK_SET);
		/*char buf[4];
		mmioRead(m_snd_info.cfp, buf, sizeof(char)*4);
		if(strnicmp("RIFF", buf, 4))
			goto OPEN_ERROR;
		//Skip file length
		mmioSeek( m_snd_info.cfp, 4, SEEK_CUR);
		mmioRead(m_snd_info.cfp, buf, sizeof(char)*4);
		if(strnicmp("WAVE", buf, 4))
			goto OPEN_ERROR;*/

		// Now read RIFF tags until the end of file
		uint tag, size, next_chunk;

		while (done == FALSE)
		{
			if (mmioRead(m_snd_info.cfp, (char*)&tag, sizeof(uint)) != sizeof(uint))
				break;

			if (mmioRead(m_snd_info.cfp, (char*)&size, sizeof(uint)) != sizeof(uint))
				break;

			next_chunk = mmioSeek(m_snd_info.cfp, 0, SEEK_CUR);
			next_chunk += size;

			switch (tag)
			{
			case 0x20746d66:		// The 'fmt ' tag
				mmioRead(m_snd_info.cfp, (char*)&pcmwf, sizeof(PCMWAVEFORMAT));
				if (pcmwf.wf.wFormatTag != WAVE_FORMAT_PCM)
				{
					mmioRead(m_snd_info.cfp, (char*)&cbExtra, sizeof(short));
				}

				// Allocate memory for WAVEFORMATEX structure + extra bytes
				if ((m_pwfmt_original = (WAVEFORMATEX*)vm_malloc(sizeof(WAVEFORMATEX) + cbExtra)) != NULL)
				{
					Assert(m_pwfmt_original != NULL);
					// Copy bytes from temporary format structure
					memcpy(m_pwfmt_original, &pcmwf, sizeof(pcmwf));
					m_pwfmt_original->cbSize = cbExtra;

					// Read those extra bytes, append to WAVEFORMATEX structure
					if (cbExtra != 0)
					{
						mmioRead(m_snd_info.cfp, (char*)((ubyte*)(m_pwfmt_original)+ sizeof(WAVEFORMATEX)), cbExtra);
					}
				}
				else
				{
					Int3();		// malloc failed
					goto OPEN_ERROR;
				}
				break;

			case 0x61746164:		// the 'data' tag
				m_nDataSize = size;	// This is size of data chunk.  Compressed if ADPCM.
				m_data_bytes_left = size;
				m_data_offset = mmioSeek(m_snd_info.cfp, 0, SEEK_CUR);
				done = TRUE;
				break;

			default:	// unknown, skip it
				break;
			}	// end switch

			mmioSeek(m_snd_info.cfp, next_chunk, SEEK_SET);
		}

		// At this stage, examine source format, and set up WAVEFORATEX structure for DirectSound.
		// Since DirectSound only supports PCM, force this structure to be PCM compliant.  We will
		// need to convert data on the fly later if our souce is not PCM
		switch (m_pwfmt_original->wFormatTag)
		{
		case WAVE_FORMAT_PCM:
			m_wave_format = WAVE_FORMAT_PCM;
			m_wfmt.wBitsPerSample = m_pwfmt_original->wBitsPerSample;
			break;

		case WAVE_FORMAT_ADPCM:
			m_wave_format = WAVE_FORMAT_ADPCM;
			if (UserSampleBits == 16 || UserSampleBits == 8)
				m_wfmt.wBitsPerSample = UserSampleBits;				//Decode at whatever the user specified, if it's 16 or 8
			else if (UserSampleBits > 16)
				m_wfmt.wBitsPerSample = 16;
			else
				m_wfmt.wBitsPerSample = 8;
			break;

		default:
			nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n",
					 m_pwfmt_original->wFormatTag));
			//Int3();
			goto OPEN_ERROR;
			break;

		} // end switch

		// Set up the WAVEFORMATEX structure to have the right PCM characteristics
		m_wfmt.wFormatTag = WAVE_FORMAT_PCM;
		m_wfmt.nChannels = m_pwfmt_original->nChannels;
		m_wfmt.nSamplesPerSec = m_pwfmt_original->nSamplesPerSec;
		m_wfmt.cbSize = 0;
		m_wfmt.nBlockAlign = (unsigned short)((m_wfmt.nChannels * m_wfmt.wBitsPerSample) / 8);
		m_wfmt.nAvgBytesPerSec = m_wfmt.nBlockAlign * m_wfmt.nSamplesPerSec;

		// Init some member data from format chunk
		m_nBlockAlign = m_pwfmt_original->nBlockAlign;
		m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec;

		// Cue for streaming
		Cue();

		// Successful open
		goto OPEN_DONE;
	}

OPEN_ERROR:
	// Handle all errors here
	nprintf(("SOUND", "SOUND ==> Could not open wave file %s for streaming\n", pszFilename));

	fRtn = FAILURE;
	if (m_snd_info.cfp != NULL)
	{
		// Close file
		mmioClose(m_snd_info.cfp, 0);
		m_snd_info.cfp = NULL;
		m_snd_info.true_offset = 0;
		m_snd_info.size = 0;
	}
	if (m_pwfmt_original)
	{
		vm_free(m_pwfmt_original);
		m_pwfmt_original = NULL;
	}

OPEN_DONE:
	return (fRtn);
}
Esempio n. 11
0
/*
=================
S_OGG_CodecOpenStream
=================
*/
snd_stream_t* S_OGG_CodecOpenStream(const char* filename) {
    snd_stream_t* stream;

    // OGG codec control structure
    OggVorbis_File* vf;

    // some variables used to get informations about the OGG
    vorbis_info* OGGInfo;
    ogg_int64_t numSamples;

    // check if input is valid
    if (!filename) {
        return NULL;
    }

    // Open the stream
    stream = S_CodecUtilOpen(filename, &ogg_codec);
    if (!stream) {
        return NULL;
    }

    // alloctate the OggVorbis_File
    vf = Z_Malloc(sizeof(OggVorbis_File));
    if (!vf) {
        S_CodecUtilClose(&stream);

        return NULL;
    }

    // open the codec with our callbacks and stream as the generic pointer
    if (ov_open_callbacks(stream, vf, NULL, 0, S_OGG_Callbacks) != 0) {
        Z_Free(vf);

        S_CodecUtilClose(&stream);

        return NULL;
    }

    // the stream must be seekable
    if (!ov_seekable(vf)) {
        ov_clear(vf);

        Z_Free(vf);

        S_CodecUtilClose(&stream);

        return NULL;
    }

    // we only support OGGs with one substream
    if (ov_streams(vf) != 1) {
        ov_clear(vf);

        Z_Free(vf);

        S_CodecUtilClose(&stream);

        return NULL;
    }

    // get the info about channels and rate
    OGGInfo = ov_info(vf, 0);
    if (!OGGInfo) {
        ov_clear(vf);

        Z_Free(vf);

        S_CodecUtilClose(&stream);

        return NULL;
    }

    // get the number of sample-frames in the OGG
    numSamples = ov_pcm_total(vf, 0);

    // fill in the info-structure in the stream
    stream->info.rate = OGGInfo->rate;
    stream->info.width = OGG_SAMPLEWIDTH;
    stream->info.channels = OGGInfo->channels;
    stream->info.samples = numSamples;
    stream->info.size = stream->info.samples * stream->info.channels * stream->info.width;
    stream->info.dataofs = 0;

    // We use stream->pos for the file pointer in the compressed ogg file
    stream->pos = 0;

    // We use the generic pointer in stream for the OGG codec control structure
    stream->ptr = vf;

    return stream;
}
Esempio n. 12
0
static BseErrorType
dh_vorbis_open (GslDataHandle      *dhandle,
		GslDataHandleSetup *setup)
{
  VorbisHandle *vhandle = (VorbisHandle*) dhandle;
  VFile *vfile;
  vorbis_info *vi;
  GslLong n, i;
  gint err;

  vfile = g_new0 (VFile, 1);
  vfile->rfile = gsl_rfile_open (vhandle->dhandle.name);
  if (!vfile->rfile)
    {
      g_free (vfile);
      return gsl_error_from_errno (errno, BSE_ERROR_FILE_OPEN_FAILED);
    }
  vfile->byte_length = gsl_rfile_length (vfile->rfile);
  if (vhandle->rfile_add_zoffset)
    {
      vfile->byte_offset = gsl_hfile_zoffset (vfile->rfile->hfile) + 1;
      vfile->byte_offset += vhandle->rfile_byte_offset;
      vfile->byte_offset = MIN (vfile->byte_offset, vfile->byte_length);
      vfile->byte_length -= vfile->byte_offset;
    }
  else
    {
      vfile->byte_offset = MIN (vhandle->rfile_byte_offset, vfile->byte_length);
      vfile->byte_length -= vfile->byte_offset;
    }
  if (vhandle->rfile_byte_length > 0)
    vfile->byte_length = MIN (vfile->byte_length, vhandle->rfile_byte_length);
  err = ov_open_callbacks (vfile, &vhandle->ofile, NULL, 0, vfile_ov_callbacks);
  if (err < 0)
    {
      if (0)
        g_printerr ("failed to open ogg at offset %d (real offset=%lld) (add-zoffset=%d): %s\n",
                    vhandle->rfile_byte_offset,
                    vfile->byte_offset,
                    vhandle->rfile_add_zoffset,
                    bse_error_blurb (ov_errno_to_error (err, BSE_ERROR_FILE_OPEN_FAILED)));
      vfile_close (vfile);
      return ov_errno_to_error (err, BSE_ERROR_FILE_OPEN_FAILED);
    }

  n = ov_streams (&vhandle->ofile);
  if (n > vhandle->bitstream)
    {
      vhandle->bitstream_serialno = ov_serialnumber (&vhandle->ofile, vhandle->bitstream);
      vhandle->n_bitstreams = n;
      if (0)
        g_printerr ("Ogg/Vorbis: opening ogg: bitstream=%d/%d serialno=%d\n", vhandle->bitstream, vhandle->n_bitstreams, vhandle->bitstream_serialno);
    }
  else
    {
      ov_clear (&vhandle->ofile); /* closes file */
      return BSE_ERROR_NO_DATA;	/* requested bitstream not available */
    }

  vhandle->soffset = 0;
  for (i = 0; i < vhandle->bitstream; i++)
    vhandle->soffset += ov_pcm_total (&vhandle->ofile, i);

  n = ov_pcm_total (&vhandle->ofile, vhandle->bitstream);
  vi = ov_info (&vhandle->ofile, vhandle->bitstream);
  if (n > 0 && vi && vi->channels && ov_pcm_seek (&vhandle->ofile, vhandle->soffset) >= 0)
    {
      setup->n_channels = vi->channels;
      setup->n_values = n * setup->n_channels;
    }
  else
    {
      ov_clear (&vhandle->ofile); /* closes file */
      return BSE_ERROR_NO_DATA;
    }

  vhandle->max_block_size = vorbis_info_blocksize (vi, 0);
  n = vorbis_info_blocksize (vi, 1);
  vhandle->max_block_size = MAX (vhandle->max_block_size, n);
  vhandle->pcm_pos = 0;
  vhandle->pcm_length = 0;
  
  setup->bit_depth = 24;
  setup->mix_freq = vi->rate;
  setup->needs_cache = TRUE;
  setup->xinfos = bse_xinfos_add_float (setup->xinfos, "osc-freq", vhandle->osc_freq);
  return BSE_ERROR_NONE;
}
Esempio n. 13
0
prMALError 
SDKOpenFile8(
	imStdParms		*stdParms, 
	imFileRef		*SDKfileRef, 
	imFileOpenRec8	*SDKfileOpenRec8)
{
	prMALError			result = malNoError;

	ImporterLocalRec8H	localRecH = NULL;
	ImporterLocalRec8Ptr localRecP = NULL;

	if(SDKfileOpenRec8->privatedata)
	{
		localRecH = (ImporterLocalRec8H)SDKfileOpenRec8->privatedata;

		stdParms->piSuites->memFuncs->lockHandle(reinterpret_cast<char**>(localRecH));

		localRecP = reinterpret_cast<ImporterLocalRec8Ptr>( *localRecH );
	}
	else
	{
		localRecH = (ImporterLocalRec8H)stdParms->piSuites->memFuncs->newHandle(sizeof(ImporterLocalRec8));
		SDKfileOpenRec8->privatedata = (PrivateDataPtr)localRecH;

		stdParms->piSuites->memFuncs->lockHandle(reinterpret_cast<char**>(localRecH));

		localRecP = reinterpret_cast<ImporterLocalRec8Ptr>( *localRecH );
		
		localRecP->vf = NULL;
		localRecP->opus = NULL;
		localRecP->flac = NULL;
		
		localRecP->importerID = SDKfileOpenRec8->inImporterID;
		localRecP->fileType = SDKfileOpenRec8->fileinfo.filetype;
	}


	SDKfileOpenRec8->fileinfo.fileref = *SDKfileRef = reinterpret_cast<imFileRef>(imInvalidHandleValue);


	if(localRecP)
	{
		const prUTF16Char *path = SDKfileOpenRec8->fileinfo.filepath;
	
	#ifdef PRWIN_ENV
		HANDLE fileH = CreateFileW(path,
									GENERIC_READ,
									FILE_SHARE_READ,
									NULL,
									OPEN_EXISTING,
									FILE_ATTRIBUTE_NORMAL,
									NULL);
									
		if(fileH != imInvalidHandleValue)
		{
			SDKfileOpenRec8->fileinfo.fileref = *SDKfileRef = fileH;
		}
		else
			result = imFileOpenFailed;
	#else
		FSIORefNum refNum = CAST_REFNUM(imInvalidHandleValue);
				
		CFStringRef filePathCFSR = CFStringCreateWithCharacters(NULL, path, prUTF16CharLength(path));
													
		CFURLRef filePathURL = CFURLCreateWithFileSystemPath(NULL, filePathCFSR, kCFURLPOSIXPathStyle, false);
		
		if(filePathURL != NULL)
		{
			FSRef fileRef;
			Boolean success = CFURLGetFSRef(filePathURL, &fileRef);
			
			if(success)
			{
				HFSUniStr255 dataForkName;
				FSGetDataForkName(&dataForkName);
			
				OSErr err = FSOpenFork(	&fileRef,
										dataForkName.length,
										dataForkName.unicode,
										fsRdWrPerm,
										&refNum);
			}
										
			CFRelease(filePathURL);
		}
									
		CFRelease(filePathCFSR);

		if(CAST_FILEREF(refNum) != imInvalidHandleValue)
		{
			SDKfileOpenRec8->fileinfo.fileref = *SDKfileRef = CAST_FILEREF(refNum);
		}
		else
			result = imFileOpenFailed;
	#endif

	}

	if(result == malNoError)
	{
		localRecP->fileType = SDKfileOpenRec8->fileinfo.filetype;
		
		assert(0 == ogg_tell_func(static_cast<void *>(*SDKfileRef)));
			
		if(localRecP->fileType == Ogg_filetype)
		{
			localRecP->vf = new OggVorbis_File;
		
			OggVorbis_File &vf = *localRecP->vf;
			
			int ogg_err = ov_open_callbacks(static_cast<void *>(*SDKfileRef), &vf, NULL, 0, g_ov_callbacks);
			
			if(ogg_err == OV_OK)
			{
				if( ov_streams(&vf) == 0 )
				{
					result = imFileHasNoImportableStreams;
					
					ov_clear(&vf);
				}
				else if( !ov_seekable(&vf) )
				{
					result = imBadFile;
				}
			}
			else
				result = imBadHeader;
		}
		else if(localRecP->fileType == Opus_filetype)
		{
			int _error = 0;
			
			localRecP->opus = op_open_callbacks(static_cast<void *>(*SDKfileRef), &g_opusfile_callbacks, NULL, 0, &_error);
			
			if(localRecP->opus != NULL && _error == 0)
			{
				assert(op_link_count(localRecP->opus) == 1); // we're not really handling multi-link scenarios
			}
			else
				result = imBadHeader;
		}
		else if(localRecP->fileType == FLAC_filetype)
		{
			try
			{
				localRecP->flac = new OurDecoder(*SDKfileRef);
				
				localRecP->flac->set_md5_checking(true);
				
				FLAC__StreamDecoderInitStatus init_status = localRecP->flac->init();
				
				assert(init_status == FLAC__STREAM_DECODER_INIT_STATUS_OK && localRecP->flac->is_valid());
				
				bool ok = localRecP->flac->process_until_end_of_metadata();
				
				assert(ok);
			}
			catch(...)
			{
				result = imBadHeader;
			}
		}
	}
	
	// close file and delete private data if we got a bad file
	if(result != malNoError)
	{
		if(SDKfileOpenRec8->privatedata)
		{
			stdParms->piSuites->memFuncs->disposeHandle(reinterpret_cast<PrMemoryHandle>(SDKfileOpenRec8->privatedata));
			SDKfileOpenRec8->privatedata = NULL;
		}
	}
	else
	{
		stdParms->piSuites->memFuncs->unlockHandle(reinterpret_cast<char**>(SDKfileOpenRec8->privatedata));
	}

	return result;
}
Esempio n. 14
0
static snd_stream_t *S_VORBIS_CodecOpenStream (const char *filename)
{
    snd_stream_t *stream;
    OggVorbis_File *ovFile;
    vorbis_info *ovf_info;
    long numstreams;
    int res;

    stream = S_CodecUtilOpen(filename, &vorbis_codec);
    if (!stream)
        return NULL;

    ovFile = (OggVorbis_File *) Z_Malloc(sizeof(OggVorbis_File));
    res = OV_OPEN_CALLBACKS(&stream->fh, ovFile, NULL, 0, ovc_qfs);
    if (res != 0)
    {
        Con_Printf("%s is not a valid Ogg Vorbis file (error %i).\n",
                   filename, res);
        goto _fail;
    }

    stream->priv = ovFile;

    if (!ov_seekable(ovFile))
    {
        Con_Printf("Stream %s not seekable.\n", filename);
        goto _fail;
    }

    ovf_info = ov_info(ovFile, 0);
    if (!ovf_info)
    {
        Con_Printf("Unable to get stream info for %s.\n", filename);
        goto _fail;
    }

    /* FIXME: handle section changes */
    numstreams = ov_streams(ovFile);
    if (numstreams != 1)
    {
        Con_Printf("More than one (%ld) stream in %s.\n",
                   numstreams, filename);
        goto _fail;
    }

    if (ovf_info->channels != 1 && ovf_info->channels != 2)
    {
        Con_Printf("Unsupported number of channels %d in %s\n",
                   ovf_info->channels, filename);
        goto _fail;
    }

    stream->info.rate = ovf_info->rate;
    stream->info.channels = ovf_info->channels;
    stream->info.width = VORBIS_SAMPLEWIDTH;

    return stream;
_fail:
    if (res == 0)
        ov_clear(ovFile);
    Z_Free(ovFile);
    S_CodecUtilClose(&stream);
    return NULL;
}
Esempio n. 15
0
int WOggDecoder::_OpenFile(unsigned int fLite)
{

	bit_stream.start = c_pchStreamStart;
	bit_stream.end = c_pchStreamStart + c_nStreamSize - 1;
	bit_stream.pos = c_pchStreamStart;
	bit_stream.size = c_nStreamSize;

	if(c_fManagedStream)
	{
		if(ov_open_callbacks(this, &vf, NULL, 0, cb) < 0)
		{
			err(DECODER_NOT_VALID_OGG_STREAM);
			return 0;
		}
	}
	else
	{
		if(ov_open_callbacks(&bit_stream, &vf, NULL, 0, cb) < 0)
		{
			err(DECODER_NOT_VALID_OGG_STREAM);
			return 0;
		}
	}

		
	if(fLite)
		return 1;

	// get number of logical streams
	c_nNumberOfLogicalBitstreams = ov_streams(&vf);

	if(c_nNumberOfLogicalBitstreams == 0)
	{
		err(DECODER_NOT_VALID_OGG_STREAM);
		return 0;
	}


	c_nLogicalBitstreamIndex = 0;

	vi = ov_info(&vf, c_nLogicalBitstreamIndex);


	if(vi == NULL)
	{
		err(DECODER_NOT_VALID_OGG_STREAM);
		return 0;	
	}


	c_isInfo.nSampleRate = vi->rate;
	c_isInfo.nChannel = vi->channels;


	c_isInfo.fVbr = 1;
	if(vi->bitrate_upper == vi->bitrate_lower)
		c_isInfo.fVbr = 0;
		
	c_isInfo.nFileBitrate = ov_bitrate(&vf, c_nLogicalBitstreamIndex);
	ogg_int64_t len = ov_pcm_total(&vf, c_nLogicalBitstreamIndex);
	if(len == OV_EINVAL)
		c_isInfo.nLength = 0;
	else	
		c_isInfo.nLength = len;


	if(c_isInfo.nChannel > 2)
		c_isInfo.pchStreamDescription = "VORBIS OGG MULTI CHANNEL";
	else if(c_isInfo.nChannel == 2)
		c_isInfo.pchStreamDescription = "VORBIS OGG STEREO";
	else
		c_isInfo.pchStreamDescription = "VORBIS OGG MONO";

	// get informations of input stream
	// WE ALWAYS USE 16 bit per sample

	// save original bit per sample

	if(c_isInfo.nChannel >= 2)
		c_nBlockAlign = 4;	
	else
		c_nBlockAlign = 2;
	
	c_isInfo.nBlockAlign = 4;		
	c_isInfo.nBitPerSample = 16;
	c_nReversePos = 0;

	c_nCurrentPosition = 0;
	c_fReady = 1;

	return 1;


}
Esempio n. 16
0
static int OGG_open(Sound_Sample *sample, const char *ext)
{
    int rc;
    double total_time;
    OggVorbis_File *vf;
    vorbis_info *info;
    Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;

    vf = (OggVorbis_File *) malloc(sizeof (OggVorbis_File));
    BAIL_IF_MACRO(vf == NULL, ERR_OUT_OF_MEMORY, 0);

    rc = ov_open_callbacks(internal->rw, vf, NULL, 0, RWops_ogg_callbacks);
    if (rc != 0)
    {
#if (defined DEBUG_CHATTER)		
        SNDDBG(("OGG: can't grok data. reason: [%s].\n", ogg_error(rc)));
#endif
        free(vf);
        BAIL_MACRO("OGG: Not valid Ogg Vorbis data.", 0);
    } /* if */

    info = ov_info(vf, -1);
    if (info == NULL)
    {
        ov_clear(vf);
        free(vf);
        BAIL_MACRO("OGG: failed to retrieve bitstream info", 0);
    } /* if */

    output_ogg_comments(vf);
	
    SNDDBG(("OGG: bitstream version == (%d).\n", info->version));
    SNDDBG(("OGG: bitstream channels == (%d).\n", info->channels));
    SNDDBG(("OGG: bitstream sampling rate == (%ld).\n", info->rate));
    SNDDBG(("OGG: seekable == {%s}.\n", ov_seekable(vf) ? "TRUE" : "FALSE"));
    SNDDBG(("OGG: number of logical bitstreams == (%ld).\n", ov_streams(vf)));
    SNDDBG(("OGG: serial number == (%ld).\n", ov_serialnumber(vf, -1)));
    SNDDBG(("OGG: total seconds of sample == (%f).\n", ov_time_total(vf, -1)));

    internal->decoder_private = vf;
    sample->flags = SOUND_SAMPLEFLAG_CANSEEK;
    sample->actual.rate = (uint32_t) info->rate;
    sample->actual.channels = (uint8_t) info->channels;
    total_time = ov_time_total(vf, -1);
    if (OV_EINVAL == total_time)
      internal->total_time = -1;
    else
      internal->total_time = (int32_t)(total_time);


    /*
     * Since we might have more than one logical bitstream in the OGG file,
     *  and these bitstreams may be in different formats, we might be
     *  converting two or three times: once in vorbisfile, once again in
     *  SDL_sound, and perhaps a third time to get it to the sound device's
     *  format. That's wickedly inefficient.
     *
     * To combat this a little, if the user specified a desired format, we
     *  claim that to be the "actual" format of the collection of logical
     *  bitstreams. This means that VorbisFile will do a conversion as
     *  necessary, and SDL_sound will not. If the user didn't specify a
     *  desired format, then we pretend the "actual" format is something that
     *  OGG files are apparently commonly encoded in.
     */
    sample->actual.format = (sample->desired.format == 0) ?
                             AUDIO_S16SYS : sample->desired.format;
    return(1);
} /* OGG_open */
Esempio n. 17
0
// Open
bool WaveFile::Open(char *pszFilename, bool keep_ext)
{
	int rc = -1;
	WORD cbExtra = 0;
	bool fRtn = true;    // assume success
	PCMWAVEFORMAT pcmwf;
	int FileSize, FileOffset;
	char fullpath[MAX_PATH];
	char filename[MAX_FILENAME_LEN];
	const int NUM_EXT = 2;
	const char *audio_ext[NUM_EXT] = { ".ogg", ".wav" };

	m_total_uncompressed_bytes_read = 0;
	m_max_uncompressed_bytes_to_read = AS_HIGHEST_MAX;

	// NOTE: we assume that the extension has already been stripped off if it was supposed to be!!
	strcpy_s( filename, pszFilename );


	// if we are supposed to load the file as passed...
	if (keep_ext) {
		for (int i = 0; i < NUM_EXT; i++) {
			if ( stristr(pszFilename, audio_ext[i]) ) {
				rc = i;
				break;
			}
		}

		// not a supported extension format ... somebody screwed up their tbls :)
		if (rc < 0)
			goto OPEN_ERROR;

		cf_find_file_location(pszFilename, CF_TYPE_ANY, sizeof(fullpath) - 1, fullpath, &FileSize, &FileOffset);
	}
	// ... otherwise we just find the best match
	else {
		rc = cf_find_file_location_ext(filename, NUM_EXT, audio_ext, CF_TYPE_ANY, sizeof(fullpath) - 1, fullpath, &FileSize, &FileOffset);
	}

	if (rc < 0) {
		goto OPEN_ERROR;
	} else {
		// set proper filename for later use (assumes that it doesn't already have an extension)
		strcat_s( filename, audio_ext[rc] );
	}

	m_snd_info.cfp = mmioOpen( fullpath, NULL, MMIO_ALLOCBUF | MMIO_READ );

	if (m_snd_info.cfp == NULL)
		goto OPEN_ERROR;

	m_snd_info.true_offset = FileOffset;
	m_snd_info.size = FileSize;

	// if in a VP then position the stream at the start of the file
	if (FileOffset > 0)
		mmioSeek( m_snd_info.cfp, FileOffset, SEEK_SET );

	// if Ogg Vorbis...
	if (rc == 0) {
		if ( ov_open_callbacks(&m_snd_info, &m_snd_info.vorbis_file, NULL, 0, mmio_callbacks) == 0 ) {
			// got an Ogg Vorbis, so lets read the info in
			ov_info(&m_snd_info.vorbis_file, -1);

			// we only support one logical bitstream
			if ( ov_streams(&m_snd_info.vorbis_file) != 1 ) {
				mprintf(("AUDIOSTR => OGG reading error:  We don't handle bitstream changes!\n"));
				goto OPEN_ERROR;
			}

			m_wave_format = OGG_FORMAT_VORBIS;
			m_wfmt.wFormatTag = WAVE_FORMAT_PCM;
			m_wfmt.nChannels = (WORD) m_snd_info.vorbis_file.vi->channels;
			m_wfmt.nSamplesPerSec = m_snd_info.vorbis_file.vi->rate;

			switch (Ds_sound_quality) {
				case DS_SQ_HIGH:
					m_wfmt.wBitsPerSample = Ds_float_supported ? 32 : 16;
					break;

				case DS_SQ_MEDIUM:
					m_wfmt.wBitsPerSample = 16;
					break;

				default:
					m_wfmt.wBitsPerSample = 8;
					break;
			}

			m_wfmt.cbSize = 0;

			m_wfmt.nBlockAlign = (ushort)(( m_wfmt.nChannels * m_wfmt.wBitsPerSample ) / 8);
			m_wfmt.nAvgBytesPerSec = m_wfmt.nSamplesPerSec * m_wfmt.nBlockAlign;

			m_nBlockAlign = m_wfmt.nBlockAlign;
			m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec;

			// location of start of file in VP
			m_data_offset = 0;
			m_nDataSize = m_data_bytes_left = ((int)ov_pcm_total(&m_snd_info.vorbis_file, -1) * m_wfmt.nBlockAlign);
		} else {
			mprintf(("AUDIOSTR => OGG reading error: Not a valid Vorbis file!\n"));
		}
	}
	// if Wave...
	else if (rc == 1) {
		bool done = false;

		// Skip the "RIFF" tag and file size (8 bytes)
		// Skip the "WAVE" tag (4 bytes)
		mmioSeek( m_snd_info.cfp, 12+FileOffset, SEEK_SET );

		// Now read RIFF tags until the end of file
		uint tag, size, next_chunk;

		while ( !done ) {
			if ( !audiostr_read_uint(m_snd_info.cfp, &tag) )
				break;

			if ( !audiostr_read_uint(m_snd_info.cfp, &size) )
				break;

			next_chunk = mmioSeek(m_snd_info.cfp, 0, SEEK_CUR );
			next_chunk += size;

			switch (tag)
			{
				case 0x20746d66:		// The 'fmt ' tag
				{
					audiostr_read_word(m_snd_info.cfp, &pcmwf.wf.wFormatTag);
					audiostr_read_word(m_snd_info.cfp, &pcmwf.wf.nChannels);
					audiostr_read_dword(m_snd_info.cfp, &pcmwf.wf.nSamplesPerSec);
					audiostr_read_dword(m_snd_info.cfp, &pcmwf.wf.nAvgBytesPerSec);
					audiostr_read_word(m_snd_info.cfp, &pcmwf.wf.nBlockAlign);
					audiostr_read_word(m_snd_info.cfp, &pcmwf.wBitsPerSample);
			
					if (pcmwf.wf.wFormatTag == WAVE_FORMAT_ADPCM)
						audiostr_read_word(m_snd_info.cfp, &cbExtra);

					// Allocate memory for WAVEFORMATEX structure + extra bytes
					if ( (m_pwfmt_original = (WAVEFORMATEX *) vm_malloc(sizeof(WAVEFORMATEX)+cbExtra)) != NULL ) {
						Assert(m_pwfmt_original != NULL);
						// Copy bytes from temporary format structure
						memcpy (m_pwfmt_original, &pcmwf, sizeof(pcmwf));
						m_pwfmt_original->cbSize = cbExtra;

						// Read those extra bytes, append to WAVEFORMATEX structure
						if (cbExtra != 0)
							mmioRead( m_snd_info.cfp, ((char *)(m_pwfmt_original) + sizeof(WAVEFORMATEX)), cbExtra );
					} else {
						Int3();		// malloc failed
						goto OPEN_ERROR;
					}

					break;
				}

				case 0x61746164:		// the 'data' tag
				{
					m_nDataSize = size;	// This is size of data chunk.  Compressed if ADPCM.
					m_data_bytes_left = size;
					m_data_offset = mmioSeek( m_snd_info.cfp, 0, SEEK_CUR );
					done = true;

					break;
				}

				default:	// unknown, skip it
					break;
			}	// end switch

			mmioSeek( m_snd_info.cfp, next_chunk, SEEK_SET );
		}

		// make sure that we did good
		if ( !done || (m_pwfmt_original == NULL) )
			goto OPEN_ERROR;

  		// At this stage, examine source format, and set up WAVEFORATEX structure for DirectSound.
		// Since DirectSound only supports PCM, force this structure to be PCM compliant.  We will
		// need to convert data on the fly later if our souce is not PCM
		switch (m_pwfmt_original->wFormatTag) {
			case WAVE_FORMAT_PCM:
				m_wave_format = WAVE_FORMAT_PCM;
				m_wfmt.wBitsPerSample = m_pwfmt_original->wBitsPerSample;
				break;

			case WAVE_FORMAT_ADPCM:
				m_wave_format = WAVE_FORMAT_ADPCM;
				m_wfmt.wBitsPerSample = (Ds_sound_quality) ? 16: 8;
				m_bits_per_sample_uncompressed = m_wfmt.wBitsPerSample;
				break;

			case WAVE_FORMAT_IEEE_FLOAT: {
				m_wave_format = WAVE_FORMAT_IEEE_FLOAT;

				switch (Ds_sound_quality) {
					case DS_SQ_HIGH:
						m_wfmt.wBitsPerSample = (Ds_float_supported) ? 32 : 16;
						break;

					case DS_SQ_MEDIUM:
						m_wfmt.wBitsPerSample = 16;
						break;

					default:
						m_wfmt.wBitsPerSample = 8;
						break;
				}

				break;
			}

			default:
				nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n", m_pwfmt_original->wFormatTag));
				goto OPEN_ERROR;
				break;

		} // end switch
            
		// Set up the WAVEFORMATEX structure to have the right PCM characteristics
		m_wfmt.wFormatTag = WAVE_FORMAT_PCM;
		m_wfmt.nChannels = m_pwfmt_original->nChannels;
		m_wfmt.nSamplesPerSec = m_pwfmt_original->nSamplesPerSec;
		m_wfmt.cbSize = 0;
		m_wfmt.nBlockAlign = (ushort)(( m_wfmt.nChannels * m_wfmt.wBitsPerSample ) / 8);
		m_wfmt.nAvgBytesPerSec = m_wfmt.nBlockAlign * m_wfmt.nSamplesPerSec;

		// Init some member data from format chunk
		m_nBlockAlign = m_pwfmt_original->nBlockAlign;
		m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec;

		Assert( (m_wfmt.nChannels == 1) || (m_wfmt.nChannels == 2) );
	}
	// something unkown???
	else {
		Int3();
	}

	m_al_format = openal_get_format(m_wfmt.wBitsPerSample, m_wfmt.nChannels);

	if (m_al_format != AL_INVALID_VALUE) {	
		// Cue for streaming
		Cue();

		goto OPEN_DONE;
	}

OPEN_ERROR:
	// Handle all errors here
	nprintf(("SOUND","SOUND ==> Could not open wave file %s for streaming\n", filename));

	fRtn = false;

	if (m_snd_info.cfp != NULL) {
		// Close file
		mmioClose( m_snd_info.cfp, 0 );
		m_snd_info.cfp = NULL;
		m_snd_info.true_offset = 0;
		m_snd_info.size = 0;
	}

	if (m_pwfmt_original) {
		vm_free(m_pwfmt_original);
		m_pwfmt_original = NULL;
	}

OPEN_DONE:
	strncpy(m_wFilename, filename, MAX_FILENAME_LEN-1);

	if (fRtn)
		nprintf(("SOUND", "AUDIOSTR => Successfully opened: %s\n", filename));

	return (fRtn);
}
Esempio n. 18
0
static int decode_file(FILE *in, FILE *out, char *infile, char *outfile)
{
    OggVorbis_File vf;
    int bs = 0;
    char buf[8192], outbuf[8192];
    char *p_outbuf;
    int buflen = 8192;
    unsigned int written = 0;
    int ret;
    ogg_int64_t length = 0;
    ogg_int64_t done = 0;
    int size = 0;
    int seekable = 0;
    int percent = 0;
    int channels;
    int samplerate;

    if (ov_open_callbacks(in, &vf, NULL, 0, OV_CALLBACKS_DEFAULT) < 0) {
        fprintf(stderr, _("ERROR: Failed to open input as Vorbis\n"));
        fclose(in);
        return 1;
    }

    channels = ov_info(&vf,0)->channels;
    samplerate = ov_info(&vf,0)->rate;

    if(ov_seekable(&vf)) {
        int link;
        int chainsallowed = 0;
        for(link = 0; link < ov_streams(&vf); link++) {
            if(ov_info(&vf, link)->channels == channels && 
                    ov_info(&vf, link)->rate == samplerate)
            {
                chainsallowed = 1;
            }
        }

        seekable = 1;
        if(chainsallowed)
            length = ov_pcm_total(&vf, -1);
        else
            length = ov_pcm_total(&vf, 0);
        size = bits/8 * channels;
        if(!quiet)
            fprintf(stderr, _("Decoding \"%s\" to \"%s\"\n"), 
                    infile?infile:_("standard input"), 
                    outfile?outfile:_("standard output"));
    }

    if(!raw) {
        if(write_prelim_header(&vf, out, length)) {
            ov_clear(&vf);
            return 1;
        }
    }

    while((ret = ov_read(&vf, buf, buflen, endian, bits/8, sign, &bs)) != 0) {
        if(bs != 0) {
            vorbis_info *vi = ov_info(&vf, -1);
            if(channels != vi->channels || samplerate != vi->rate) {
                fprintf(stderr, _("Logical bitstreams with changing parameters are not supported\n"));
                break;
            }
        }

        if(ret < 0 ) {
           if( !quiet ) {
               fprintf(stderr, _("WARNING: hole in data (%d)\n"), ret);
           }
            continue;
        }

        if(channels > 2 && !raw) {
          /* Then permute! */
          permute_channels(buf, outbuf, ret, channels, bits/8);
          p_outbuf = outbuf;
        }
        else {
          p_outbuf = buf;
        }

        if(fwrite(p_outbuf, 1, ret, out) != ret) {
            fprintf(stderr, _("Error writing to file: %s\n"), strerror(errno));
            ov_clear(&vf);
            return 1;
        }

        written += ret;
        if(!quiet && seekable) {
            done += ret/size;
            if((double)done/(double)length * 200. > (double)percent) {
                percent = (int)((double)done/(double)length *200);
                fprintf(stderr, "\r\t[%5.1f%%]", (double)percent/2.);
            }
        }
    }

    if(seekable && !quiet)
        fprintf(stderr, "\n");

    if(!raw)
        rewrite_header(out, written); /* We don't care if it fails, too late */

    ov_clear(&vf);

    return 0;
}
/* Reads an ogg vorbis file, infile, and dumps the data into
   a big buffer, *pcmbuffer (which it allocates via malloc)
   and returns the number of samples in *nsamples, and the
   samplesize in *samplesize. and etc.
*/
int ogg_to_pcm(char *infile, int16_t **pcmbuffer,
	int *samplesize, int *sample_rate, int *nchannels,
	uint64_t *nsamples)
{
	OggVorbis_File vf;
	char buf[8192];
	unsigned char *bufferptr;
	int link, ret, chainsallowed = 0, bs = 0;

	/* how to do this portably at compile time? */
	const uint32_t dummy = 0x01020304;
	const unsigned char *endian = (unsigned char *) &dummy;

	/* use ov_fopen to avoid runtime conflicts on win32 */
	if (ov_fopen(infile, &vf) < 0) {
		fprintf(stderr, "%s:%d: ERROR: Failed to open '%s' as vorbis\n",
			__FILE__, __LINE__, infile);
		ov_clear(&vf);
		return -1;
	}
	if (!ov_seekable(&vf)) {
		fprintf(stderr, "%s:%d: %s is not seekable.\n",
			__FILE__, __LINE__, infile);
		ov_clear(&vf);
		return -1;
	}

	*nchannels = ov_info(&vf,0)->channels;
	*sample_rate = ov_info(&vf,0)->rate;

	for (link = 0; link < ov_streams(&vf); link++) {
		if (ov_info(&vf, link)->channels == *nchannels &&
		    ov_info(&vf, link)->rate == *sample_rate) {
			chainsallowed = 1;
		}
	}

	if (chainsallowed)
		*nsamples = ov_pcm_total(&vf, -1);
	else
		*nsamples = ov_pcm_total(&vf, 0);

	*pcmbuffer = (void *) malloc(sizeof(int16_t) * *nsamples * *nchannels);
	memset(*pcmbuffer, 0, sizeof(int16_t) * *nsamples * *nchannels);
	if (*pcmbuffer == NULL) {
		fprintf(stderr, "%s:%d: Failed to allocate memory for '%s'\n",
			__FILE__, __LINE__, infile);
		ov_clear(&vf);
		return -1;
	}
	bufferptr = (unsigned char *) *pcmbuffer;

	while ((ret = ov_read(&vf, buf, sizeof(buf), endian[0] == 0x01, bits/8, 1, &bs)) != 0) {
		if (bs != 0) {
			vorbis_info *vi = ov_info(&vf, -1);
			if (*nchannels != vi->channels || *sample_rate != vi->rate) {
				fprintf(stderr, "%s:%d: Logical bitstreams with changing "
					"parameters are not supported\n",
					__FILE__, __LINE__);
				break;
			}
		}

		if(ret < 0 ) {
			fprintf(stderr, "%s:%d: Warning: hole in data (%d)\n",
				__FILE__, __LINE__, ret);
			continue;
		}

		/* copy the data to the pcmbuffer. */
		memcpy(bufferptr, buf, ret);
		bufferptr += ret;
	}

	/* ov_clear closes the file, so don't fclose here, even though we fopen()ed.
	 * libvorbis is weird that way.
 	 */
	ov_clear(&vf);

	return 0;
}