コード例 #1
0
ファイル: SampleBuffer.cpp プロジェクト: floft/lmms
f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f,
						int_sample_t * & _buf,
						ch_cnt_t & _channels,
						sample_rate_t & _samplerate )
{
	static ov_callbacks callbacks =
	{
		qfileReadCallback,
		qfileSeekCallback,
		qfileCloseCallback,
		qfileTellCallback
	} ;

	OggVorbis_File vf;

	f_cnt_t frames = 0;

	QFile * f = new QFile( _f );
	if( f->open( QFile::ReadOnly ) == false )
	{
		delete f;
		return 0;
	}

	int err = ov_open_callbacks( f, &vf, NULL, 0, callbacks );

	if( err < 0 )
	{
		switch( err )
		{
			case OV_EREAD:
				printf( "SampleBuffer::decodeSampleOGGVorbis():"
						" media read error\n" );
				break;
			case OV_ENOTVORBIS:
/*				printf( "SampleBuffer::decodeSampleOGGVorbis():"
					" not an Ogg Vorbis file\n" );*/
				break;
			case OV_EVERSION:
				printf( "SampleBuffer::decodeSampleOGGVorbis():"
						" vorbis version mismatch\n" );
				break;
			case OV_EBADHEADER:
				printf( "SampleBuffer::decodeSampleOGGVorbis():"
					" invalid Vorbis bitstream header\n" );
				break;
			case OV_EFAULT:
				printf( "SampleBuffer::decodeSampleOgg(): "
					"internal logic fault\n" );
				break;
		}
		delete f;
		return 0;
	}

	ov_pcm_seek( &vf, 0 );

   	_channels = ov_info( &vf, -1 )->channels;
   	_samplerate = ov_info( &vf, -1 )->rate;

	ogg_int64_t total = ov_pcm_total( &vf, -1 );

	_buf = new int_sample_t[total * _channels];
	int bitstream = 0;
	long bytes_read = 0;

	do
	{
		bytes_read = ov_read( &vf, (char *) &_buf[frames * _channels],
					( total - frames ) * _channels *
							BYTES_PER_INT_SAMPLE,
					isLittleEndian() ? 0 : 1,
					BYTES_PER_INT_SAMPLE, 1, &bitstream );
		if( bytes_read < 0 )
		{
			break;
		}
		frames += bytes_read / ( _channels * BYTES_PER_INT_SAMPLE );
	}
	while( bytes_read != 0 && bitstream == 0 );

	ov_clear( &vf );
	// if buffer isn't empty, convert it to float and write it down

	if ( frames > 0 && _buf != NULL )
	{
		convertIntToFloat ( _buf, frames, _channels);
	}

	return frames;
}
コード例 #2
0
ファイル: soundbuffer.cpp プロジェクト: HaohaoLau/vdrift
bool SoundBuffer::LoadOGG(const std::string & filename, const SoundInfo & sound_device_info, std::ostream & error_output)
{
	if (loaded)
		Unload();

	name = filename;

	FILE *fp;

	unsigned int samples;

	fp = fopen(filename.c_str(), "rb");
	if (fp)
	{
		vorbis_info *pInfo;
		OggVorbis_File oggFile;

		ov_open_callbacks(fp, &oggFile, NULL, 0, OV_CALLBACKS_DEFAULT);

		pInfo = ov_info(&oggFile, -1);

		//I assume ogg is always 16-bit (2 bytes per sample) -Venzon
		samples = ov_pcm_total(&oggFile,-1);
		info = SoundInfo(samples*pInfo->channels, pInfo->rate, pInfo->channels, 2);

		SoundInfo desired_info(info.samples, sound_device_info.frequency, info.channels, sound_device_info.bytespersample);

		if (!(desired_info == info))
		{
			error_output << "SOUND FORMAT:" << std::endl;
			info.DebugPrint(error_output);
			error_output << "DESIRED FORMAT:" << std::endl;
			desired_info.DebugPrint(error_output);

			error_output << "Sound file isn't in desired format: "+filename << std::endl;
			ov_clear(&oggFile);
			return false;
		}

		//allocate space
		unsigned int size = info.samples*info.channels*info.bytespersample;
		sound_buffer = new char[size];
		int bitstream;
		int endian = 0; //0 for Little-Endian, 1 for Big-Endian
		int wordsize = 2; //again, assuming ogg is always 16-bits
		int issigned = 1; //use signed data

		int bytes = 1;
		unsigned int bufpos = 0;
		while (bytes > 0)
		{
			bytes = ov_read(&oggFile, sound_buffer+bufpos, size-bufpos, endian, wordsize, issigned, &bitstream);
			bufpos += bytes;
			//cout << bytes << "...";
		}

		loaded = true;

		//note: no need to call fclose(); ov_clear does it for us
		ov_clear(&oggFile);

		return true;
	}
	else
	{
		error_output << "Can't open sound file: "+filename << std::endl;
		return false;
	}
}
コード例 #3
0
ファイル: ogg.c プロジェクト: sesc4mt/mvcdecoder
/* Function: al_load_ogg_vorbis_audio_stream_f
 */
ALLEGRO_AUDIO_STREAM *al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE* file,
	size_t buffer_count, unsigned int samples)
{
   const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */
   OggVorbis_File* vf;
   vorbis_info* vi;
   int channels;
   long rate;
   long total_samples;
   long total_size;
   AL_OV_DATA* extra;
   ALLEGRO_AUDIO_STREAM* stream;

   extra = _AL_MALLOC(sizeof(AL_OV_DATA));
   if (extra == NULL) {
      ALLEGRO_ERROR("Failed to allocate AL_OV_DATA struct.\n");
      return NULL;
   }
   
   if (file == NULL) {
      ALLEGRO_WARN("File failed to open\n");
      fprintf(stderr, "File failed to open\n");
      return NULL;
   }
   
   extra->file = file;
   
   vf = _AL_MALLOC(sizeof(OggVorbis_File));
   if (ov_open_callbacks(extra, vf, NULL, 0, callbacks) < 0) {
      ALLEGRO_WARN("ogg: Input does not appear to be an Ogg bitstream.\n");
      al_fclose(file);
      return NULL;
   }

   extra->vf = vf;

   vi = ov_info(vf, -1);
   channels = vi->channels;
   rate = vi->rate;
   total_samples = ov_pcm_total(vf,-1);
   total_size = total_samples * channels * word_size;

   extra->vi = vi;

   extra->bitstream = -1;

   ALLEGRO_DEBUG("channels %d\n", channels);
   ALLEGRO_DEBUG("word_size %d\n", word_size);
   ALLEGRO_DEBUG("rate %ld\n", rate);
   ALLEGRO_DEBUG("total_samples %ld\n", total_samples);
   ALLEGRO_DEBUG("total_size %ld\n", total_size);
	
   stream = al_create_audio_stream(buffer_count, samples, rate,
            _al_word_size_to_depth_conf(word_size),
            _al_count_to_channel_conf(channels));
   if (!stream) {
      free(vf);
      return NULL;
   }

   stream->extra = extra;

   extra->loop_start = 0.0;
   extra->loop_end = ogg_stream_get_length(stream);
   stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream);
   stream->quit_feed_thread = false;
   stream->feeder = ogg_stream_update;
   stream->rewind_feeder = ogg_stream_rewind;
   stream->seek_feeder = ogg_stream_seek;
   stream->get_feeder_position = ogg_stream_get_position;
   stream->get_feeder_length = ogg_stream_get_length;
   stream->set_feeder_loop = ogg_stream_set_loop;
   stream->unload_feeder = ogg_stream_close;
   al_start_thread(stream->feed_thread);
	
   return stream;
}
コード例 #4
0
ファイル: Sound.cpp プロジェクト: Deepsloth/freeorion
void Sound::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/)
{
    if (!GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled()))
        return;

    std::string filename = path.string();
    ALuint current_buffer;
    ALenum source_state;
    ALsizei ogg_freq;
    FILE *file = 0;
    int m_i;
    bool found_buffer = true;
    bool found_source = false;

#ifdef FREEORION_WIN32
    ov_callbacks callbacks = {

    (size_t (*)(void *, size_t, size_t, void *))  fread,

    (int (*)(void *, ogg_int64_t, int))           _fseek64_wrap,

    (int (*)(void *))                             fclose,

    (long (*)(void *))                            ftell

    };
#endif

    if (alcGetCurrentContext() != 0)
    {
        /* First check if the sound data of the file we want to play is already buffered somewhere */
        std::map<std::string, ALuint>::iterator it = m_buffers.find(filename);
        if (it != m_buffers.end())
            current_buffer = it->second;
        else {
            if ((file = fopen(filename.c_str(), "rb")) != 0) // make sure we CAN open it
            {
                OggVorbis_File ogg_file;
                vorbis_info *vorbis_info;
                ALenum ogg_format;
#ifdef FREEORION_WIN32
                if (!(ov_test_callbacks(file, &ogg_file, 0, 0, callbacks))) // check if it's a proper ogg
#else
                if (!(ov_test(file, &ogg_file, 0, 0))) // check if it's a proper ogg
#endif
                {
                    ov_test_open(&ogg_file); // it is, now fully open the file
                    /* now we need to take some info we will need later */
                    vorbis_info = ov_info(&ogg_file, -1);
                    if (vorbis_info->channels == 1)
                        ogg_format = AL_FORMAT_MONO16;
                    else
                        ogg_format = AL_FORMAT_STEREO16;
                    ogg_freq = vorbis_info->rate;
                    ogg_int64_t byte_size = ov_pcm_total(&ogg_file, -1) * vorbis_info->channels * 2;
                    if (byte_size <= 1024 * 1024 * 1024) {
                        /* fill up the buffers and queue them up for the first time */
                        ALuint sound_handle;
                        alGenBuffers(1, &sound_handle);

                        int loop = 0;

                        RefillBuffer(&ogg_file, ogg_format, ogg_freq, sound_handle, byte_size, loop);

                        current_buffer = sound_handle;
                        m_buffers.insert(std::make_pair(filename, sound_handle));
                    }
                    else
                    {
                        ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " too big to buffer. Aborting\n";
                    }
                    ov_clear(&ogg_file);
                }
                else
                {
                    ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n";
                }
            }
        }
        if (found_buffer) {
            /* Now that we have the buffer, we need to find a source to send it to */
            for (m_i = 1; m_i < NUM_SOURCES; ++m_i) {   // as we're playing sounds we start at 1. 0 is reserved for music
                alGetSourcei(m_sources[m_i],AL_SOURCE_STATE,&source_state);
                if ((source_state != AL_PLAYING) && (source_state != AL_PAUSED)) {
                    found_source = true;
                    alSourcei(m_sources[m_i], AL_BUFFER, current_buffer);
                    alSourcePlay(m_sources[m_i]);
                    break; // so that the sound won't block all the sources
                }
            }
            if (!found_source)
                ErrorLogger() << "PlaySound: Could not find aviable source - playback aborted\n";
        }
        source_state = alGetError();
        if (source_state != AL_NONE)
            ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(source_state);
            /* it's important to check for errors, as some functions won't work properly if
             * they're called when there is a unchecked previous error. */
    }
}
コード例 #5
0
int64 OggVorbisReader::FrameCount(void)
{
 return(ov_pcm_total(&ovfile, -1));
}
コード例 #6
0
 int getSourceLength(){
   if(isplaying_ogg)
     return ov_pcm_total(&oggvorbisfile,-1);
   return N;
 }
コード例 #7
0
ファイル: filevorbis.C プロジェクト: beequ7et/cinelerra-cv
// Just create the Quicktime objects since this routine is also called
// for reopening.
int FileVorbis::open_file(int rd, int wr)
{
	int result = 0;
	this->rd = rd;
	this->wr = wr;

//printf("FileVorbis::open_file 1\n");
	if(rd)
	{
//printf("FileVorbis::open_file 1\n");
		if(!(fd = fopen(asset->path, "rb")))
		{
			eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
			result = 1;
		}
		else
		{
//printf("FileVorbis::open_file 2 %p %p\n", fd, vf);
			if(ov_open(fd, &vf, NULL, 0) < 0)
			{
				eprintf("Invalid bitstream in %s\n", asset->path);
				result = 1;
			}
			else
			{
//printf("FileVorbis::open_file 1\n");
				vorbis_info *vi = ov_info(&vf, -1);
				asset->channels = vi->channels;
				if(!asset->sample_rate)
					asset->sample_rate = vi->rate;
//printf("FileVorbis::open_file 1\n");
				asset->audio_length = ov_pcm_total(&vf,-1);
//printf("FileVorbis::open_file 1\n");
				asset->audio_data = 1;
// printf("FileVorbis::open_file 1 %d %d %d\n", 
// asset->channels, 
// asset->sample_rate, 
// asset->audio_length);
			}
		}
	}

	if(wr)
	{
		if(!(fd = fopen(asset->path, "wb")))
		{
			eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
			result = 1;
		}
		else
		{
			vorbis_info_init(&vi);
			if(!asset->vorbis_vbr)
				result = vorbis_encode_init(&vi, 
					asset->channels, 
					asset->sample_rate, 
					asset->vorbis_max_bitrate, 
					asset->vorbis_bitrate, 
					asset->vorbis_min_bitrate);
			else
			{
				result = vorbis_encode_setup_managed(&vi,
					asset->channels, 
					asset->sample_rate, 
					asset->vorbis_max_bitrate, 
					asset->vorbis_bitrate, 
					asset->vorbis_min_bitrate);
				result |= vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_AVG, NULL);
				result |= vorbis_encode_setup_init(&vi);
			}

			if(!result)
			{
				vorbis_analysis_init(&vd, &vi);
				vorbis_block_init(&vd, &vb);
				vorbis_comment_init(&vc);
				srand(time(NULL));
				ogg_stream_init(&os, rand());

				ogg_packet header;
				ogg_packet header_comm;
				ogg_packet header_code;
				vorbis_analysis_headerout(&vd, 
					&vc,
					&header,
					&header_comm,
					&header_code);
				ogg_stream_packetin(&os,
					&header);
				ogg_stream_packetin(&os, 
					&header_comm);
				ogg_stream_packetin(&os,
					&header_code);

				while(1)
				{
					int result = ogg_stream_flush(&os, &og);
					if(result == 0) break;
					fwrite(og.header, 1, og.header_len, fd);
					fwrite(og.body, 1, og.body_len, fd);
				}
			}
		}
	}

//printf("FileVorbis::open_file 2\n");
	return result;
}
コード例 #8
0
bool OggResourceLoader::ParseOgg(char* oggStream, size_t bufferLength, shared_ptr<ResHandle> handle)
{
	shared_ptr<SoundResourceExtraData> extra = static_pointer_cast<SoundResourceExtraData>(handle->GetExtra());

	OggVorbis_File vf;

	ov_callbacks oggCallbacks;

	// create the vorbis memory object
	OggMemoryFile* vorbisMemoryFile = CB_NEW OggMemoryFile;
	vorbisMemoryFile->dataSize = bufferLength;
	vorbisMemoryFile->dataPtr = (unsigned char*)oggStream;
	vorbisMemoryFile->dataRead = 0;

	// set up ogg callbacks
	oggCallbacks.read_func = VorbisRead;
	oggCallbacks.close_func = VorbisClose;
	oggCallbacks.seek_func = VorbisSeek;
	oggCallbacks.tell_func = VorbisTell;

	int ov_ret = ov_open_callbacks(vorbisMemoryFile, &vf, nullptr, 0, oggCallbacks);
	CB_ASSERT(ov_ret >= 0);

	vorbis_info* vi = ov_info(&vf, -1);

	ZeroMemory(&(extra->m_WavFormatEx), sizeof(extra->m_WavFormatEx));

	// set up the extra info
	extra->m_WavFormatEx.cbSize = sizeof(extra->m_WavFormatEx);
	extra->m_WavFormatEx.nChannels = vi->channels;
	extra->m_WavFormatEx.wBitsPerSample = 16;
	extra->m_WavFormatEx.nSamplesPerSec = vi->rate;
	extra->m_WavFormatEx.nAvgBytesPerSec = extra->m_WavFormatEx.nSamplesPerSec * extra->m_WavFormatEx.nChannels * 2;
	extra->m_WavFormatEx.nBlockAlign = extra->m_WavFormatEx.nChannels * 2;
	extra->m_WavFormatEx.wFormatTag = 1;

	DWORD size = 4096 * 16;
	DWORD pos = 0;
	int sec = 0;
	int ret = 1;

	DWORD bytes = (DWORD)ov_pcm_total(&vf, -1);
	bytes *= 2 * vi->channels;

	if (handle->Size() != bytes)
	{
		CB_ASSERT(0 && L"The Ogg size does not match the memory buffer size");
		ov_clear(&vf);
		CB_SAFE_DELETE(vorbisMemoryFile);
		return false;
	}

	// read in the bytes
	while (ret && pos < bytes)
	{
		ret = ov_read(&vf, handle->WritableBuffer() + pos, size, 0, 2, 1, &sec);
		pos += ret;

		if (bytes - pos < size)
		{
			size = bytes - pos;
		}
	}

	extra->m_LengthMilliseconds = (int)(1000.0f * ov_time_total(&vf, -1));

	ov_clear(&vf);
	CB_SAFE_DELETE(vorbisMemoryFile);
	
	return true;
}
コード例 #9
0
ファイル: seeking_example.c プロジェクト: Chocobo1/vorbis
int main(){
  OggVorbis_File ov;
  int i,ret;
  ogg_int64_t pcmlength;
  double timelength;
  char *bigassbuffer;
  int dummy;
  int hs=0;

#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  _setmode( _fileno( stdin ), _O_BINARY );
#endif


  /* open the file/pipe on stdin */
  if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
    fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
    exit(1);
  }

#if 0 /*enable this code to test seeking with halfrate decode */
  if(ov_halfrate(&ov,1)){
    fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n");
    exit(1);
  }else
    hs=1;
#endif

  if(ov_seekable(&ov)){

    /* to simplify our own lives, we want to assume the whole file is
       stereo.  Verify this to avoid potentially mystifying users
       (pissing them off is OK, just don't confuse them) */
    for(i=0;i<ov.links;i++){
      vorbis_info *vi=ov_info(&ov,i);
      if(vi->channels!=2){
        fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
               "that are entirely stereo.\n\n");
        exit(1);
      }
    }

    /* because we want to do sample-level verification that the seek
       does what it claimed, decode the entire file into memory */
    pcmlength=ov_pcm_total(&ov,-1);
    timelength=ov_time_total(&ov,-1);
    bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */
    i=0;
    while(i<(pcmlength>>hs)*2){
      int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy);
      if(ret<0){
        fprintf(stderr,"Error reading file.\n");
        exit(1);
      }
      if(ret){
        i+=ret;
      }else{
        pcmlength=(i/2)<<hs;
      }
      fprintf(stderr,"\rloading.... [%ld left]              ",
              (long)((pcmlength>>hs)*2-i));
    }

    {
      ogg_int64_t length=ov.end;
      fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
             (long)length);

      for(i=0;i<1000;i++){
        ogg_int64_t val=(double)rand()/RAND_MAX*length;
        fprintf(stderr,"\r\t%d [raw position %ld]...     ",i,(long)val);
        ret=ov_raw_seek(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }

        _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
             (long)pcmlength);

      for(i=0;i<1000;i++){
        ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
        fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
        ret=ov_pcm_seek_page(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }

        _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing pcm exact seeking to random places in %f seconds....\n",
             timelength);
      for(i=0;i<1000;i++){
        ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
        fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
        ret=ov_pcm_seek(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }
        if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){
          fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
                 (long)val,(long)ov_pcm_tell(&ov));
          exit(1);
        }

        _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
             timelength);
    
      for(i=0;i<1000;i++){
        double val=(double)rand()/RAND_MAX*timelength;
        fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
        ret=ov_time_seek_page(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }

        _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
             timelength);
    
      for(i=0;i<1000;i++){
        double val=(double)rand()/RAND_MAX*timelength;
        fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
        ret=ov_time_seek(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }
        if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
          fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
                 val,ov_time_tell(&ov));
          exit(1);
        }

        _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);

      }
    }
    
    fprintf(stderr,"\r                                           \nOK.\n\n");


  }else{
コード例 #10
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;
}
コード例 #11
0
int ogg_decoder(const char *ogg_file, const char *pcm_file)
{
	OggVorbis_File vf;
	int eof = 0;
	int current_section;
	int tm1, tm2;
	FILE *fin, *fout;

	//open the ogg file
	fin = fopen(ogg_file, "rb");
	if (fin == NULL)
	{
		libc_printf("open the ogg file: %s failed!\n", ogg_file);
		return -1;
	}

	//create the pcm file
#if 0
	fout = fopen(pcm_file, "wb");
	if (fout == NULL)
	{
		libc_printf("open the ogg file: %s failed!\n", pcm_file);
		return -1;
	}
#endif

	if (ov_open(fin, &vf, NULL, 0) < 0)
	{
		libc_printf("Input does not appear to be an Ogg bitstream.\n");
		return -1;
	}

	/* Throw the comments plus a few lines about the bitstream we're
	   decoding */
	{
		char **ptr = ov_comment(&vf, -1)->user_comments;
		vorbis_info *vi = ov_info(&vf, -1);
		while (*ptr)
		{
			libc_printf("%s\n", *ptr);
			++ptr;
		}
		libc_printf("\nBitstream is %d channel, %ldHz\n", vi->channels, vi->rate);
		libc_printf("\nDecoded length: %ld samples\n",
					(long)ov_pcm_total(&vf, -1));
		libc_printf("Encoded by: %s\n\n", ov_comment(&vf, -1)->vendor);
	}

	tm1 = osal_get_tick();


	while (!eof)
	{
		long ret = ov_read(&vf, pcmout, sizeof(pcmout), &current_section);
		if (ret == 0)
		{
			libc_printf("file end!\n");
			/* EOF */
			eof = 1;
		}
		else if (ret < 0)
		{
			libc_printf("error!!!\n");
			/* error in the stream.  Not a problem, just reporting it in
			case we (the app) cares.  In this case, we don't. */
		}
		else
		{
			/* we don't bother dealing with sample rate changes, etc, but
			you'll have to*/
			//fwrite(pcmout, ret, 1, fout);
		}
	}


	/* cleanup */
	ov_clear(&vf);
	tm2 = osal_get_tick();
	libc_printf("decoding time: %dms [%d ~ %d]\n", tm2 - tm1, tm1, tm2);

	//fclose(fout);

	libc_printf("Done.\n");
	return(0);
}
コード例 #12
0
ファイル: soundsourceoggvorbis.cpp プロジェクト: MK-42/mixxx
SoundSource::OpenResult SoundSourceOggVorbis::tryOpen(
        OpenMode /*mode*/,
        const OpenParams& /*config*/) {
    m_pFile = std::make_unique<QFile>(getLocalFileName());
    if (!m_pFile->open(QFile::ReadOnly)) {
        kLogger.warning()
                << "Failed to open file for"
                << getUrlString();
        return OpenResult::Failed;
    }

    const int initDecoderResult = ov_open_callbacks(m_pFile.get(), &m_vf, nullptr, 0, s_callbacks);
    switch (initDecoderResult) {
    case 0:
        // success -> continue
        break;
    case OV_ENOTVORBIS:
    case OV_EVERSION:
        kLogger.warning()
            << "Unsupported format in"
            << getUrlString();
        return OpenResult::Aborted;
    default:
        kLogger.warning()
            << "Failed to initialize decoder for"
            << getUrlString();
        return OpenResult::Failed;
    }

    if (!ov_seekable(&m_vf)) {
        kLogger.warning()
                << "Stream in"
                << getUrlString()
                << "is not seekable";
        return OpenResult::Aborted;
    }

    // lookup the ogg's channels and sample rate
    const vorbis_info* vi = ov_info(&m_vf, kCurrentBitstreamLink);
    if (!vi) {
        kLogger.warning()
                << "Failed to read stream info from"
                << getUrlString();
        return OpenResult::Failed;
    }
    setChannelCount(vi->channels);
    setSampleRate(vi->rate);
    if (0 < vi->bitrate_nominal) {
        initBitrateOnce(vi->bitrate_nominal / 1000);
    } else {
        if ((0 < vi->bitrate_lower) && (vi->bitrate_lower == vi->bitrate_upper)) {
            initBitrateOnce(vi->bitrate_lower / 1000);
        }
    }

    ogg_int64_t pcmTotal = ov_pcm_total(&m_vf, kEntireBitstreamLink);
    if (0 <= pcmTotal) {
        initFrameIndexRangeOnce(IndexRange::forward(0, pcmTotal));
    } else {
        kLogger.warning()
                << "Failed to read read total length of"
                << getUrlString();
        return OpenResult::Failed;
    }

    return OpenResult::Succeeded;
}
コード例 #13
0
bool SoundManager::loadOgg(FILE* file, ALuint buffer)
{
	OggVorbis_File ogg_file;
	vorbis_info* info;
	ALenum format;
	int result;
	int section;
	unsigned int size = 0;

	rewind(file);

	if ((result = ov_open(file, &ogg_file, NULL, 0)) < 0) {
		fclose(file);
		qDebug() << "Failed to open ogg file.";
		return false;
	}

	info = ov_info(&ogg_file, -1);

	if (info->channels == 1)
		format = AL_FORMAT_MONO16;
	else
		format = AL_FORMAT_STEREO16;

	// size = #samples * #channels * 2 (for 16 bit).
	unsigned int data_size = ov_pcm_total(&ogg_file, -1) * info->channels * 2;
	char* data = new char[data_size];

	while (size < data_size) {
		result = ov_read(&ogg_file, data + size, data_size - size, 0, 2, 1, &section);
		if (result > 0) {
			size += result;
		}
		else if (result < 0) {
			delete data;
			qDebug() << "Failed to read ogg file; file is missing data.";
			return false;
		}
		else {
			break;
		}
	}

	if (size == 0) {
		delete data;
		qDebug() << "Filed to read ogg file; unable to read any data.";
		return false;
	}

	alBufferData(buffer, format, data, data_size, info->rate);

	ALenum error = alGetError();
	if (error != AL_NO_ERROR) {
		reportOpenALError(error);
	}

	delete data;
	ov_clear(&ogg_file);

	// ov_clear actually closes the file pointer as well.
	file = 0;

	return true;
}
コード例 #14
0
  std::pair<ALuint, float> Sound_Buffer::load_ogg_vorbis(const String &
#ifndef DISABLE_AL
    filename
#endif
    ) {

#ifndef DISABLE_AL
    /*** Open VorbisFile ***/

    OggVorbis_File oggFile;
    if(ov_fopen(const_cast<char *>((filename + ".ogg").c_str()), &oggFile))
      return std::make_pair(AL_NONE, 0.0f);

    /*** Get Information About the Audio File ***/

    vorbis_info *pInfo = ov_info(&oggFile, -1);
    const ALenum format = pInfo->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
    const ALsizei freq = ALsizei(pInfo->rate);
    const ALsizei bytes_per_sample = format == AL_FORMAT_STEREO16 ? 4 : 2;
    const ogg_int64_t num_samples = ov_pcm_total(&oggFile, -1);
    const ogg_int64_t pcm_size = num_samples * bytes_per_sample;
    const float duration = float(num_samples) / freq;

#ifndef NDEBUG
    if(format == AL_FORMAT_STEREO16)
      std::cerr << "WARNING: '" << filename << "' is stereo and will be unaffected by the OpenAL positional audio system." << std::endl;
#endif

    /*** Load the Audio File ***/

    long bytes = 0;
    ogg_int64_t remaining = pcm_size;
    if(pcm_size > std::numeric_limits<size_t>::max())
      throw Sound_Buffer_Init_Failure();
    std::vector<char> buffer(static_cast<size_t>(pcm_size));
    for(char *begin = &buffer[0], *end = begin + pcm_size;
        begin != end;
        begin += bytes, remaining -= bytes)
    {
      int read_size = remaining > std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : int(remaining);
      bytes = ov_read(&oggFile, begin, read_size, 0, 2, 1, 0);

      if(bytes < 0) {
        ov_clear(&oggFile);
        throw Sound_Buffer_Init_Failure();
      }
    }

    /*** Generate Audio Buffer ***/

    ALuint bufferID = AL_NONE;
    Sound_Renderer_AL::alGenBuffers()(1, &bufferID);
    Sound_Renderer_AL::alBufferData()(bufferID, format, &buffer[0], static_cast<ALsizei>(buffer.size()), freq);

    return std::make_pair(bufferID, duration);

#else

    return std::make_pair(AL_NONE, 0.0f);

#endif

  }
コード例 #15
0
ファイル: ogg_vorbis_file.c プロジェクト: 9a3eedi/Droidsound
VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const char * filename, ov_callbacks *callbacks_p, off_t other_header_bytes, const vgm_vorbis_info_t *vgm_inf) {
    VGMSTREAM * vgmstream = NULL;

    OggVorbis_File temp_ovf;
    ogg_vorbis_streamfile temp_streamfile;

    ogg_vorbis_codec_data * data = NULL;
    OggVorbis_File *ovf;
    int inited_ovf = 0;
    vorbis_info *info;

    int loop_flag = vgm_inf->loop_flag;
    int32_t loop_start = vgm_inf->loop_start;
    int loop_length_found = vgm_inf->loop_length_found;
    int32_t loop_length = vgm_inf->loop_length;
    int loop_end_found = vgm_inf->loop_end_found;
    int32_t loop_end = vgm_inf->loop_end;

    ov_callbacks default_callbacks;

    if (!callbacks_p) {
        default_callbacks.read_func = read_func;
        default_callbacks.seek_func = seek_func;
        default_callbacks.close_func = close_func;
        default_callbacks.tell_func = tell_func;

        if (vgm_inf->scd_xor != 0) {
            default_callbacks.read_func = read_func_scd;
        }

        callbacks_p = &default_callbacks;
    }

    temp_streamfile.streamfile = streamFile;
    temp_streamfile.offset = 0;
    temp_streamfile.size = get_streamfile_size(temp_streamfile.streamfile);
    temp_streamfile.other_header_bytes = other_header_bytes;
    temp_streamfile.scd_xor  = vgm_inf->scd_xor;
    temp_streamfile.scd_xor_len = vgm_inf->scd_xor_len;

    /* can we open this as a proper ogg vorbis file? */
    memset(&temp_ovf, 0, sizeof(temp_ovf));
    if (ov_test_callbacks(&temp_streamfile, &temp_ovf, NULL,
            0, *callbacks_p)) goto fail;

    /* we have to close this as it has the init_vgmstream meta-reading
       STREAMFILE */
    ov_clear(&temp_ovf);

    /* proceed to open a STREAMFILE just for this stream */
    data = calloc(1,sizeof(ogg_vorbis_codec_data));
    if (!data) goto fail;

    data->ov_streamfile.streamfile = streamFile->open(streamFile,filename,
            STREAMFILE_DEFAULT_BUFFER_SIZE);
    if (!data->ov_streamfile.streamfile) goto fail;
    data->ov_streamfile.offset = 0;
    data->ov_streamfile.size = get_streamfile_size(data->ov_streamfile.streamfile);
    data->ov_streamfile.other_header_bytes = other_header_bytes;
    data->ov_streamfile.scd_xor  = vgm_inf->scd_xor;
    data->ov_streamfile.scd_xor_len = vgm_inf->scd_xor_len;

    /* open the ogg vorbis file for real */
    if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL,
                0, *callbacks_p)) goto fail;
    ovf = &data->ogg_vorbis_file;
    inited_ovf = 1;

    data->bitstream = DEFAULT_BITSTREAM;

    info = ov_info(ovf,DEFAULT_BITSTREAM);

    /* grab the comments */
    {
        int i;
        vorbis_comment *comment;

        comment = ov_comment(ovf,DEFAULT_BITSTREAM);

        /* search for a "loop_start" comment */
        for (i=0;i<comment->comments;i++) {
            if (strstr(comment->user_comments[i],"loop_start=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LOOP_START=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"COMMENT=LOOPPOINT=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LOOPSTART=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"um3.stream.looppoint.start=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LOOP_BEGIN=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LoopStart=")==
                    comment->user_comments[i]
                    ) {
                loop_start=atol(strrchr(comment->user_comments[i],'=')+1);
                if (loop_start >= 0)
                    loop_flag=1;
            }
            else if (strstr(comment->user_comments[i],"LOOPLENGTH=")==
                    comment->user_comments[i]) {
                loop_length=atol(strrchr(comment->user_comments[i],'=')+1);
                loop_length_found=1;
            }
            else if (strstr(comment->user_comments[i],"title=-lps")==
                    comment->user_comments[i]) {
                loop_start=atol(comment->user_comments[i]+10);
                if (loop_start >= 0)
                    loop_flag=1;
            }
            else if (strstr(comment->user_comments[i],"album=-lpe")==
                    comment->user_comments[i]) {
                loop_end=atol(comment->user_comments[i]+10);
                loop_flag=1;
                loop_end_found=1;
            }
            else if (strstr(comment->user_comments[i],"LoopEnd=")==
                    comment->user_comments[i]) {
						if(loop_flag) {
							loop_length=atol(strrchr(comment->user_comments[i],'=')+1)-loop_start;
							loop_length_found=1;
						}
            }
            else if (strstr(comment->user_comments[i],"LOOP_END=")==
                    comment->user_comments[i]) {
						if(loop_flag) {
							loop_length=atol(strrchr(comment->user_comments[i],'=')+1)-loop_start;
							loop_length_found=1;
						}
            }
            else if (strstr(comment->user_comments[i],"lp=")==
                    comment->user_comments[i]) {
                sscanf(strrchr(comment->user_comments[i],'=')+1,"%d,%d",
                        &loop_start,&loop_end);
                loop_flag=1;
                loop_end_found=1;
            }
        }
    }

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(info->channels,loop_flag);
    if (!vgmstream) goto fail;

    /* store our fun extra datas */
    vgmstream->codec_data = data;

    /* fill in the vital statistics */
    vgmstream->channels = info->channels;
    vgmstream->sample_rate = info->rate;

    /* let's play the whole file */
    vgmstream->num_samples = ov_pcm_total(ovf,-1);

    if (loop_flag) {
        vgmstream->loop_start_sample = loop_start;
        if (loop_length_found)
            vgmstream->loop_end_sample = loop_start+loop_length;
        else if (loop_end_found)
            vgmstream->loop_end_sample = loop_end;
        else
            vgmstream->loop_end_sample = vgmstream->num_samples;
        vgmstream->loop_flag = loop_flag;

        if (vgmstream->loop_end_sample > vgmstream->num_samples)
            vgmstream->loop_end_sample = vgmstream->num_samples;
    }
    vgmstream->coding_type = coding_ogg_vorbis;
    vgmstream->layout_type = vgm_inf->layout_type;
    vgmstream->meta_type = vgm_inf->meta_type;

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (data) {
        if (inited_ovf)
            ov_clear(&data->ogg_vorbis_file);
        if (data->ov_streamfile.streamfile)
            close_streamfile(data->ov_streamfile.streamfile);
        free(data);
    }
    if (vgmstream) {
        vgmstream->codec_data = NULL;
        close_vgmstream(vgmstream);
    }
    return NULL;
}
コード例 #16
0
ファイル: vorbisfile.c プロジェクト: OS2World/LIB-SDL
int ov_raw_seek(OggVorbis_File *vf,long pos){
  ogg_stream_state work_os;

  if(vf->ready_state<OPENED)return(OV_EINVAL);
  if(!vf->seekable)
    return(OV_ENOSEEK); /* don't dump machine if we can't seek */

  if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
  
  /* clear out decoding machine state */
  vf->pcm_offset=-1;
  _decode_clear(vf);
  
  _seek_helper(vf,pos);

  /* we need to make sure the pcm_offset is set, but we don't want to
     advance the raw cursor past good packets just to get to the first
     with a granulepos.  That's not equivalent behavior to beginning
     decoding as immediately after the seek position as possible.

     So, a hack.  We use two stream states; a local scratch state and
     a the shared vf->os stream state.  We use the local state to
     scan, and the shared state as a buffer for later decode. 

     Unfortuantely, on the last page we still advance to last packet
     because the granulepos on the last page is not necessarily on a
     packet boundary, and we need to make sure the granpos is
     correct. 
  */

  {
    ogg_page og;
    ogg_packet op;
    int lastblock=0;
    int accblock=0;
    int thisblock=-1;
    int eosflag=0;

    memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
					  it later even if we don't
					  init it */

    while(1){
      if(vf->ready_state==STREAMSET){
	/* snarf/scan a packet if we can */
	int result=ogg_stream_packetout(&work_os,&op);
      
	if(result>0){

	  if(vf->vi[vf->current_link].codec_setup)
	    thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
	  if(eosflag)
	    ogg_stream_packetout(&vf->os,NULL);
	  else
	    if(lastblock)accblock+=(lastblock+thisblock)>>2;

	  if(op.granulepos!=-1){
	    int i,link=vf->current_link;
	    ogg_int64_t granulepos=op.granulepos;
	    
	    for(i=0;i<link;i++)
	      granulepos+=vf->pcmlengths[i];
	    vf->pcm_offset=granulepos-accblock;
	    break;
	  }
	  lastblock=thisblock;
	  continue;
	}
      }
      
      if(!lastblock){
	if(_get_next_page(vf,&og,-1)<0){
	  vf->pcm_offset=ov_pcm_total(vf,-1);
	  break;
	}
      }else{
	/* huh?  Bogus stream with packets but no granulepos */
	vf->pcm_offset=-1;
	break;
      }
      
      /* has our decoding just traversed a bitstream boundary? */
      if(vf->ready_state==STREAMSET)
	if(vf->current_serialno!=ogg_page_serialno(&og)){
	_decode_clear(vf); /* clear out stream state */
	ogg_stream_clear(&work_os);
      }

      if(vf->ready_state<STREAMSET){
	int link;
	
	vf->current_serialno=ogg_page_serialno(&og);
	for(link=0;link<vf->links;link++)
	  if(vf->serialnos[link]==vf->current_serialno)break;
	if(link==vf->links)goto seek_error; /* sign of a bogus stream.
					       error out, leave
					       machine uninitialized */
	vf->current_link=link;
	
	ogg_stream_init(&vf->os,vf->current_serialno);
	ogg_stream_reset(&vf->os); 
	ogg_stream_init(&work_os,vf->current_serialno);
	ogg_stream_reset(&work_os); 
	vf->ready_state=STREAMSET;
	
      }
    
      ogg_stream_pagein(&vf->os,&og);
      ogg_stream_pagein(&work_os,&og);
      eosflag=ogg_page_eos(&og);
    }
  }
コード例 #17
0
ファイル: sfx.cpp プロジェクト: Asqwel/TZOD-Modified
static void ogg_load_vorbis(const char *filename, WAVEFORMATEX *pwf, std::vector<char> *data)
{
	SafePtr<FS::Stream> s = g_fs->Open(filename)->QueryStream();

	ov_callbacks cb;
	cb.read_func  = read_func;
	cb.seek_func  = seek_func;
	cb.close_func = NULL;
	cb.tell_func  = tell_func;

	OggVorbis_File vf;
	if( int result = ov_open_callbacks(GetRawPtr(s), &vf, NULL, 0, cb) )
	{
		switch( result )
		{
		case OV_EREAD: throw std::runtime_error("A read from media returned an error");
		case OV_ENOTVORBIS: throw std::runtime_error("Bitstream does not contain any Vorbis data");
		case OV_EVERSION: throw std::runtime_error("Vorbis version mismatch");
		case OV_EBADHEADER: throw std::runtime_error("Invalid Vorbis bitstream header");
		case OV_EFAULT: throw std::runtime_error("Internal logic fault; indicates a bug or heap/stack corruption");
		}
		throw std::runtime_error("unknown error opening ov stream");
	}

	try
	{
		vorbis_info *pinfo = ov_info(&vf, -1);
		if( NULL == pinfo )
		{
			throw std::runtime_error("could not get info from ov stream");
		}


		pwf->wFormatTag       = WAVE_FORMAT_PCM;
		pwf->nChannels        = pinfo->channels;
		pwf->nSamplesPerSec   = pinfo->rate;
		pwf->nAvgBytesPerSec  = pinfo->rate * pinfo->channels * 2;
		pwf->nBlockAlign      = pinfo->channels * 2;
		pwf->wBitsPerSample   = 16;
		pwf->cbSize           = 0;

		size_t size = ov_pcm_total(&vf, -1) * pwf->nBlockAlign;
		data->resize(size);

		int    bitstream = 0;
		size_t total = 0;

		while( total < size )
		{
			long ret = ov_read(&vf, &data->at(total), size - total, 0, 2, 1, &bitstream);
			if( 0 == ret )
			{
				break; // eof
			}
			if( ret < 0 )
			{
				// error in stream
				switch( ret )
				{
				case OV_HOLE:
					throw std::runtime_error("garbage between pages, loss of sync followed by recapture, or a corrupt page");
				case OV_EBADLINK:
					throw std::runtime_error("invalid stream section or the requested link is corrupt");
				case OV_EINVAL:
					throw std::runtime_error("initial file headers couldn't be read or are corrupt");
				}
				throw std::runtime_error("unknown error in ov stream");
			}
			else
			{
				total += ret;
			}
		}
	}
	catch(...)
	{
		ov_clear(&vf);
		throw;
	}
	ov_clear(&vf);
}
コード例 #18
0
uint64 CDAFReader_Vorbis::FrameCount(void)
{
    return(ov_pcm_total(&ovfile, -1));
}
コード例 #19
0
ファイル: AudioBuffer.cpp プロジェクト: 5guo/GamePlay
bool AudioBuffer::loadOgg(Stream* stream, ALuint buffer)
{
    GP_ASSERT(stream);

    OggVorbis_File ogg_file;
    vorbis_info* info;
    ALenum format;
    long result;
    int section;
    long size = 0;

    stream->rewind();

    ov_callbacks callbacks;
    callbacks.read_func = readStream;
    callbacks.seek_func = seekStream;
    callbacks.close_func = closeStream;
    callbacks.tell_func = tellStream;

    if ((result = ov_open_callbacks(stream, &ogg_file, NULL, 0, callbacks)) < 0)
    {
        GP_ERROR("Failed to open ogg file.");
        return false;
    }

    info = ov_info(&ogg_file, -1);
    GP_ASSERT(info);
    if (info->channels == 1)
        format = AL_FORMAT_MONO16;
    else
        format = AL_FORMAT_STEREO16;

    // size = #samples * #channels * 2 (for 16 bit).
    long data_size = ov_pcm_total(&ogg_file, -1) * info->channels * 2;
    char* data = new char[data_size];

    while (size < data_size)
    {
        result = ov_read(&ogg_file, data + size, data_size - size, 0, 2, 1, &section);
        if (result > 0)
        {
            size += result;
        }
        else if (result < 0)
        {
            SAFE_DELETE_ARRAY(data);
            GP_ERROR("Failed to read ogg file; file is missing data.");
            return false;
        }
        else
        {
            break;
        }
    }
    
    if (size == 0)
    {
        SAFE_DELETE_ARRAY(data);
        GP_ERROR("Filed to read ogg file; unable to read any data.");
        return false;
    }

    AL_CHECK( alBufferData(buffer, format, data, data_size, info->rate) );

    SAFE_DELETE_ARRAY(data);
    ov_clear(&ogg_file);

    return true;
}
コード例 #20
0
ファイル: music_ogg.c プロジェクト: jpmac26/PGE-Project
/* Load an OGG stream from an SDL_RWops object */
OGG_music *OGG_new_RW(SDL_RWops *src, int freesrc)
{
    OGG_music *music;
    ov_callbacks callbacks;

    if(!Mix_Init(MIX_INIT_OGG))
        return(NULL);

    SDL_memset(&callbacks, 0, sizeof(callbacks));
    callbacks.read_func = sdl_read_func;
    callbacks.seek_func = sdl_seek_func;
    callbacks.tell_func = sdl_tell_func;

    music = (OGG_music *)SDL_malloc(sizeof * music);
    if(music)
    {
        vorbis_info *vi;
        vorbis_comment *ptr;
        int isLength = 0;
        int i;
        ogg_int64_t total;

        /* Initialize the music structure */
        SDL_memset(music, 0, (sizeof * music));
        music->src = src;
        music->freesrc = freesrc;
        OGG_stop(music);
        OGG_setvolume(music, MIX_MAX_VOLUME);
        music->section = -1;
        music->channels = 0;

        music->mus_title = NULL;
        music->mus_artist = NULL;
        music->mus_album = NULL;
        music->mus_copyright = NULL;

        MyResample_zero(&music->resample);

        music->loop         = -1;
        music->loop_start   = -1;
        music->loop_end     =  0;
        music->loop_len     =  0;

        if(vorbis.ov_open_callbacks(src, &music->vf, NULL, 0, callbacks) < 0)
        {
            SDL_SetError("Not an Ogg Vorbis audio stream");
            SDL_free(music);
            return(NULL);
        }

        vi = vorbis.ov_info(&music->vf, -1);
        music->channels = vi->channels;

        /* Parse comments and extract title and loop points */
        ptr = ov_comment(&music->vf, -1);

        for(i = 0; i < ptr->comments; i++)
        {
            int   paramLen = ptr->comment_lengths[i] + 1;
            char *param = (char *)SDL_malloc(paramLen);
            char *argument  = param;
            char *value     = param;
            memset(param, 0, paramLen);
            memcpy(param, ptr->user_comments[i], ptr->comment_lengths[i]);
            value = strchr(param, '=');
            if(value == NULL)
            {
                value = param + paramLen - 1; /* set null */
            } else {
                *(value++) = '\0';
            }

            #ifdef __USE_ISOC99
#define A_TO_OGG64(x) (ogg_int64_t)atoll(x)
            #else
#define A_TO_OGG64(x) (ogg_int64_t)atol(x)
            #endif

            if(strcasecmp(argument, "LOOPSTART") == 0)
                music->loop_start = A_TO_OGG64(value);
            else if(strcasecmp(argument, "LOOPLENGTH") == 0)
            {
                music->loop_len = A_TO_OGG64(value);
                isLength = 1;
            }
            else if(strcasecmp(argument, "LOOPEND") == 0)
            {
                isLength = 0;
                music->loop_end = A_TO_OGG64(value);
            }
            else if(strcasecmp(argument, "TITLE") == 0)
            {
                music->mus_title = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1);
                strcpy(music->mus_title, value);
            }
            else if(strcasecmp(argument, "ARTIST") == 0)
            {
                music->mus_artist = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1);
                strcpy(music->mus_artist, value);
            }
            else if(strcasecmp(argument, "ALBUM") == 0)
            {
                music->mus_album = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1);
                strcpy(music->mus_album, value);
            }
            else if(strcasecmp(argument, "COPYRIGHT") == 0)
            {
                music->mus_copyright = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1);
                strcpy(music->mus_copyright, value);
            }

            SDL_free(param);
        }

#undef A_TO_OGG64

        if(isLength == 1)
            music->loop_end = music->loop_start + music->loop_len;
        else
            music->loop_len = music->loop_end - music->loop_start;

        total = ov_pcm_total(&music->vf, -1);
        if(((music->loop_start >= 0) || (music->loop_end > 0)) &&
           ((music->loop_start < music->loop_end) || (music->loop_end == 0)) &&
           (music->loop_start < total) &&
           (music->loop_end <= total))
        {
            if(music->loop_start < 0)
                music->loop_start = 0;
            if(music->loop_end == 0)
                music->loop_end = total;
            music->loop = 1;
            music->loop_len_ch = music->channels;
        }
    }
    else
    {
        SDL_OutOfMemory();
        return(NULL);
    }

    return (music);
}
コード例 #21
0
void OggVorbisFileReader::Read(Stream::IStream& stream)
{
   OggVorbis_File vf;

   // open file
   OggVorbisStreamCallbacks callbacks(false, stream.CanSeek());

   int iRet = ov_open_callbacks(&stream, &vf, NULL, 0, callbacks);
   if (iRet == -1)
   {
      ov_clear(&vf);
      throw Exception(_T("Ogg Vorbis: couldn't open file"), __FILE__, __LINE__);
   }

   // get metadata
   {
      vorbis_info* vi = ov_info(&vf, -1); // vi doesn't need to be freed
      if (vi == NULL)
      {
         ov_clear(&vf);
         throw Exception(_T("Ogg Vorbis: couldn't get info"), __FILE__, __LINE__);
      }

      m_uiChannels = vi->channels;
      m_uiSamplerate = vi->rate;
   }

   // prepare buffer
   ogg_int64_t ilLength = ov_pcm_total(&vf, -1);

   // double number of samples when stereo
   if (m_uiChannels == 2)
      ilLength <<= 1;

   ATLASSERT(ilLength >= 0 && ilLength <= std::numeric_limits<size_t>::max());
   size_t uiLength = static_cast<size_t>(ilLength);

   m_vecSamples.resize(uiLength);

   // read in samples
   int iCurrentBitstream = 0;
   bool bEof = false;
   size_t ulAlreadyRead = 0;
   while(!bEof)
   {
      // read 64k samples at once
      int iLengthToRead = std::min(int(uiLength - ulAlreadyRead), 65536);

      if (iLengthToRead == 0)
      {
         bEof = true;
         break;
      }

      long lRet = ov_read(&vf,
         reinterpret_cast<char*>(&m_vecSamples[ulAlreadyRead]),
         iLengthToRead * 2, // in bytes
         0, // big endian: no
         2, // size of word
         1, // signed: yes
         &iCurrentBitstream);

      if (lRet == 0)
         bEof = true;
      else if (lRet < 0)
      {
         // error in the stream
         break;
      }
      else
      {
         // ov_read returns number of bytes written, so divide by size of word
         ulAlreadyRead += lRet / 2;
      }
   }

   // finished
   ov_clear(&vf);

   // when not at EOF, we had an error
   if (!bEof)
      throw Exception(_T("Ogg Vorbis: couldn't read samples"), __FILE__, __LINE__);
}
コード例 #22
0
 int64 FrameCount(void)
 {
  return(ov_pcm_total(&ovfile, -1));
 }
コード例 #23
0
prMALError 
SDKGetInfo8(
	imStdParms			*stdParms, 
	imFileAccessRec8	*fileAccessInfo8, 
	imFileInfoRec8		*SDKFileInfo8)
{
	prMALError					result				= malNoError;


	SDKFileInfo8->hasDataRate						= kPrFalse;


	// private data
	assert(SDKFileInfo8->privatedata);
	ImporterLocalRec8H ldataH = reinterpret_cast<ImporterLocalRec8H>(SDKFileInfo8->privatedata);
	stdParms->piSuites->memFuncs->lockHandle(reinterpret_cast<char**>(ldataH));
	ImporterLocalRec8Ptr localRecP = reinterpret_cast<ImporterLocalRec8Ptr>( *ldataH );


	SDKFileInfo8->hasVideo = kPrFalse;
	SDKFileInfo8->hasAudio = kPrFalse;
	
	
	if(localRecP)
	{
		if(localRecP->fileType == Ogg_filetype && localRecP->vf != NULL)
		{
			OggVorbis_File &vf = *localRecP->vf;
		
			vorbis_info *info = ov_info(&vf, 0);
		
			// Audio information
			SDKFileInfo8->hasAudio				= kPrTrue;
			SDKFileInfo8->audInfo.numChannels	= info->channels;
			SDKFileInfo8->audInfo.sampleRate	= info->rate;
			SDKFileInfo8->audInfo.sampleType	= kPrAudioSampleType_Compressed;
													
			SDKFileInfo8->audDuration			= ov_pcm_total(&vf, 0);
		}
		else if(localRecP->fileType == Opus_filetype && localRecP->opus != NULL)
		{
			SDKFileInfo8->hasAudio				= kPrTrue;
			SDKFileInfo8->audInfo.numChannels	= op_channel_count(localRecP->opus, -1);
			SDKFileInfo8->audInfo.sampleRate	= 48000; // Ogg Opus always uses 48 kHz
			SDKFileInfo8->audInfo.sampleType	= kPrAudioSampleType_Compressed;
													
			SDKFileInfo8->audDuration			= op_pcm_total(localRecP->opus, -1);
		}
		else if(localRecP->fileType == FLAC_filetype && localRecP->flac != NULL)
		{
			try
			{
				SDKFileInfo8->hasAudio				= kPrTrue;
				SDKFileInfo8->audInfo.numChannels	= localRecP->flac->get_channels();
				SDKFileInfo8->audInfo.sampleRate	= localRecP->flac->get_sample_rate();
				
				int bitDepth = localRecP->flac->get_bits_per_sample();
				
				SDKFileInfo8->audInfo.sampleType	= bitDepth == 8 ? kPrAudioSampleType_8BitInt :
														bitDepth == 16 ? kPrAudioSampleType_16BitInt :
														bitDepth == 24 ? kPrAudioSampleType_24BitInt :
														bitDepth == 32 ? kPrAudioSampleType_32BitInt :
														bitDepth == 64 ? kPrAudioSampleType_64BitFloat :
														kPrAudioSampleType_Compressed;
														
				SDKFileInfo8->audDuration			= localRecP->flac->get_total_samples();
			}
			catch(...)
			{
				result = imBadFile;
			}
		}

		localRecP->audioSampleRate			= SDKFileInfo8->audInfo.sampleRate;
		localRecP->numChannels				= SDKFileInfo8->audInfo.numChannels;
		
		
		if(SDKFileInfo8->audInfo.numChannels > 2 && SDKFileInfo8->audInfo.numChannels != 6)
		{
			// Premiere can't handle anything but Mono, Stereo, and 5.1
			result = imUnsupportedAudioFormat;
		}
	}
		
	stdParms->piSuites->memFuncs->unlockHandle(reinterpret_cast<char**>(ldataH));

	return result;
}
コード例 #24
0
ALboolean loadOgg(  const char *fname,
                    void **wave,
                    ALsizei *format,
                    ALsizei *size,
                    ALsizei *bits,
                    ALsizei *freq )
{
    *format  = 0;

    OggVorbis_File vf;
    memset(&vf, 0, sizeof(vf));
    int eof = 0;
    int current_section;

  
    long ret;

    FILE * file = fopen(fname,"rb+");


//ov_open could take long and should be called in a thread
    //INFO: If the program crashes here and you are compiling under windows, make sure your
    //      debugging option equals "Multithreaded DLL"
    if(ov_open(file, &vf, NULL, 0) < 0) {
        fprintf(stderr,"\n");
        fclose(file);
        throw Exception(std::string("Input ") + fname + " does not appear to be an Ogg bitstream.");
    }

    {
        vorbis_info *vi=ov_info(&vf,-1);

        *freq = (ALsizei) vi->rate;
        /************* HACK? ************/
        *size = (ALsizei) ov_pcm_total(&vf, -1)*2;
        
        *bits = (ALsizei) 16; //ov_read returns PCM 16-bit little-endian samples

        int channels = vi->channels;        
        if (channels == 1)
        {
            *format = AL_FORMAT_MONO16;
        } else if (channels == 2)
        {
            *format = AL_FORMAT_STEREO16;
        } else
        {
            return AL_FALSE;
        }
    }

    char * pcm_data = new char[*size];
    char * pcm_data_p = pcm_data;


    while(!eof)
    {
      ret=ov_read(&vf,(char *)pcm_data_p,4096,0,2,1,&current_section);
        if (ret == 0)
        {
            /* EOF */
            eof=1;
        } else if (ret < 0)
        {
            /* error in the stream.  Not a problem, just reporting it in
               case we (the app) cares.  In this case, we don't. */
            return AL_FALSE;
        } else
        {
            /* we don't bother dealing with sample rate changes, etc, but
               you'll have to*/

            pcm_data_p += ret;
        
        }
    }


    /* cleanup */
    ov_clear(&vf);
    
    *wave = pcm_data;

    return AL_TRUE;
}
コード例 #25
0
ファイル: ogg.cpp プロジェクト: manushanga/vrok
uint64_t OGGDecoder::getLength()
{
    return ov_pcm_total(&vf,-1);
}
コード例 #26
0
int main(int argc, char *argv[]){
  OggVorbis_File vf;
  int eof=0;
  int current_section;
  FILE *fp;
int dev=0;		
    
char **ptr;
vorbis_info *vi;
#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
if(argc < 2)
{
	printf("Usage : ivorbisfile_example <ogg filename>\n");
	exit(0);
}
fp = fopen(argv[1],"rb");
if(fp == NULL)
	printf("File open error\n");		
  //if(ov_open(stdin, &vf, NULL, 0) < 0) {
  if(ov_open(fp, &vf, NULL, 0) < 0) {
      fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
      exit(1);
  }
  /* Throw the comments plus a few lines about the bitstream we're
     decoding */
 // {
    ptr=ov_comment(&vf,-1)->user_comments;
    vi=ov_info(&vf,-1);
    while(*ptr){
      fprintf(stderr,"%s\n",*ptr);
      ++ptr;
	//printf(". \n");		
    }
    fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate);
    fprintf(stderr,"\nDecoded length: %ld samples\n",
	    (long)ov_pcm_total(&vf,-1));
    fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor);
 // }

if ((dev = open(DEV, O_RDWR)) < 1) {
	printf("Device open failed");
}
 #if 1
{
  int i, v;
  v = vi->rate/2;//22050;
  i = ioctl(dev, SNDCTL_DSP_SPEED, &v);
  fprintf(stderr, "%s(%d): ioctl(SNDCTL_DSP_SPEED)=%d, set=%d\n",
	__FILE__, __LINE__, i, v);
  v = 1;
  i = ioctl(dev, SNDCTL_DSP_STEREO, &v);
  fprintf(stderr, "%s(%d): ioctl(SNDCTL_DSP_STEREO)=%d, set=%d\n",
	__FILE__, __LINE__, i, v);
  v = AFMT_S16_BE;
  i = ioctl(dev, SNDCTL_DSP_SAMPLESIZE, &v);
  fprintf(stderr, "%s(%d): ioctl(SNDCTL_DSP_SAMPLESIZE)=%d, set=%d\n",
	__FILE__, __LINE__, i, v);
}
#endif
 
#if 0
{
  int i, v;
  v = 44100;
  i = ioctl(fileno(stdout), SNDCTL_DSP_SPEED, &v);
  fprintf(stderr, "%s(%d): ioctl(SNDCTL_DSP_SPEED)=%d, set=%d\n",
	__FILE__, __LINE__, i, v);
  v = 1;
  i = ioctl(fileno(stdout), SNDCTL_DSP_STEREO, &v);
  fprintf(stderr, "%s(%d): ioctl(SNDCTL_DSP_STEREO)=%d, set=%d\n",
	__FILE__, __LINE__, i, v);
  v = AFMT_S16_BE;
  i = ioctl(fileno(stdout), SNDCTL_DSP_SAMPLESIZE, &v);
  fprintf(stderr, "%s(%d): ioctl(SNDCTL_DSP_SAMPLESIZE)=%d, set=%d\n",
	__FILE__, __LINE__, i, v);
}
#endif

  while(!eof){
    long ret=ov_read(&vf,pcmout,sizeof(pcmout),&current_section);
//	printf("\nRet = %d\n",ret);	
    if (ret == 0) {
      /* EOF */
      eof=1;
    } else if (ret < 0) {
      /* error in the stream.  Not a problem, just reporting it in
	 case we (the app) cares.  In this case, we don't. */
    } else {
      /* we don't bother dealing with sample rate changes, etc, but
	 you'll have to*/
      //fwrite(pcmout,1,ret,stdout);
      write(dev,pcmout,ret);
    }
  }

  /* cleanup */
  ov_clear(&vf);
    
  fprintf(stderr,"Done.\n");
  return(0);
}
コード例 #27
0
ファイル: ogg.c プロジェクト: sesc4mt/mvcdecoder
/* Function: al_load_ogg_vorbis_f
 */
ALLEGRO_SAMPLE *al_load_ogg_vorbis_f(ALLEGRO_FILE* file)
{
   /* Note: decoding library returns floats.  I always return 16-bit (most
    * commonly supported).
    */
#ifdef ALLEGRO_LITTLE_ENDIAN
   const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */
#else
   const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */
#endif
   int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */
   int signedness = 1; /* 0  for unsigned, 1 for signed */
   const int packet_size = 4096; /* suggestion for size to read at a time */
   OggVorbis_File vf;
   vorbis_info* vi;
   char *buffer;
   long pos;
   ALLEGRO_SAMPLE *sample;
   int channels;
   long rate;
   long total_samples;
   int bitstream;
   long total_size;
   AL_OV_DATA ov;

   if (file == NULL) {
      ALLEGRO_WARN("Audio file failed to open.\n");
      return NULL;
   }
   ov.file = file;
   if (ov_open_callbacks(&ov, &vf, NULL, 0, callbacks) < 0) {
      ALLEGRO_WARN("Audio file does not appear to be an Ogg bitstream.\n");
      al_fclose(file);
      return NULL;
   }

   vi = ov_info(&vf, -1);

   channels = vi->channels;
   rate = vi->rate;
   total_samples = ov_pcm_total(&vf, -1);
   bitstream = -1;
   total_size = total_samples * channels * word_size;

   ALLEGRO_DEBUG("channels %d\n", channels);
   ALLEGRO_DEBUG("word_size %d\n", word_size);
   ALLEGRO_DEBUG("rate %ld\n", rate);
   ALLEGRO_DEBUG("total_samples %ld\n", total_samples);
   ALLEGRO_DEBUG("total_size %ld\n", total_size);

   buffer = _AL_MALLOC_ATOMIC(total_size);
   if (!buffer) {
      al_fclose(file);
      return NULL;
   }

   pos = 0;
   while (pos < total_size) {
      /* XXX error handling */
#if !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE)
      long read = ov_read(&vf, buffer + pos, packet_size, endian, word_size,
         signedness, &bitstream);
#else
      (void)endian;
      (void)signedness;
      long read = ov_read(&vf, buffer + pos, packet_size, &bitstream);
#endif
      pos += read;
      if (read == 0)
         break;
   }

   ov_clear(&vf);

   sample = al_create_sample(buffer, total_samples, rate,
      _al_word_size_to_depth_conf(word_size),
      _al_count_to_channel_conf(channels), true);

   if (!sample) {
      _AL_FREE(buffer);
   }

   return sample;
}
コード例 #28
0
ファイル: cOggDecoder.cpp プロジェクト: Coks/cAudio
	int cOggDecoder::getTotalSize()
	{
		return ov_pcm_total(&oggStream, -1) * vorbisInfo->channels;
	}
コード例 #29
0
ファイル: oggdec.c プロジェクト: Chocobo1/vorbis-tools
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;
}
コード例 #30
0
ファイル: Audio.cpp プロジェクト: MagnusTiberius/humus3
SoundID Audio::addSound(const char *fileName, unsigned int flags){
	Sound sound;

	// Clear error flag
	alGetError();

	const char *ext = strrchr(fileName, '.') + 1;
	char str[256];
	if (stricmp(ext, "ogg") == 0){
		FILE *file = fopen(fileName, "rb");
		if (file == NULL){
			sprintf(str, "Couldn't open \"%s\"", fileName);
			ErrorMsg(str);
			return SOUND_NONE;
		}

		OggVorbis_File vf;
		memset(&vf, 0, sizeof(vf));
		if (ov_open(file, &vf, NULL, 0) < 0){
			fclose(file);
			sprintf(str, "\"%s\" is not an ogg file", fileName);
			ErrorMsg(str);
			return SOUND_NONE;
		}

		vorbis_info *vi = ov_info(&vf, -1);

		int nSamples = (uint) ov_pcm_total(&vf, -1);
		int nChannels = vi->channels;
		sound.format = nChannels == 1? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
		sound.sampleRate = vi->rate;

		sound.size = nSamples * nChannels;

		sound.samples = new short[sound.size];
		sound.size *= sizeof(short);

		int samplePos = 0;
		while (samplePos < sound.size){
			char *dest = ((char *) sound.samples) + samplePos;

			int bitStream, readBytes = ov_read(&vf, dest, sound.size - samplePos, 0, 2, 1, &bitStream);
			if (readBytes <= 0) break;
			samplePos += readBytes;
		}

		ov_clear(&vf);

	} else {
		ALboolean al_bool;
		ALvoid *data;
		alutLoadWAVFile(fileName, &sound.format, &data, &sound.size, &sound.sampleRate, &al_bool);
		sound.samples = (short *) data;
	}

	alGenBuffers(1, &sound.buffer);
	alBufferData(sound.buffer, sound.format, sound.samples, sound.size, sound.sampleRate);
	if (alGetError() != AL_NO_ERROR){
		alDeleteBuffers(1, &sound.buffer);

		sprintf(str, "Couldn't open \"%s\"", fileName);
		ErrorMsg(str);
		return SOUND_NONE;
	}

	return insertSound(sound);
}