Example #1
0
static gint
vorbis_check_fd(const gchar *filename, VFSFile *stream)
{
    OggVorbis_File vfile;
    gint result;

    /*
     * The open function performs full stream detection and machine
     * initialization.  If it returns zero, the stream *is* Vorbis and
     * we're fully ready to decode.
     */

    memset(&vfile, 0, sizeof(vfile));

    result = ov_test_callbacks (stream, & vfile, NULL, 0, vfs_is_streaming
     (stream) ? vorbis_callbacks_stream : vorbis_callbacks);

    switch (result) {
    case OV_EREAD:
#ifdef DEBUG
        g_message("** vorbis.c: Media read error: %s", filename);
#endif
        return FALSE;
        break;
    case OV_ENOTVORBIS:
#ifdef DEBUG
        g_message("** vorbis.c: Not Vorbis data: %s", filename);
#endif
        return FALSE;
        break;
    case OV_EVERSION:
#ifdef DEBUG
        g_message("** vorbis.c: Version mismatch: %s", filename);
#endif
        return FALSE;
        break;
    case OV_EBADHEADER:
#ifdef DEBUG
        g_message("** vorbis.c: Invalid Vorbis bistream header: %s",
                  filename);
#endif
        return FALSE;
        break;
    case OV_EFAULT:
#ifdef DEBUG
        g_message("** vorbis.c: Internal logic fault while reading %s",
                  filename);
#endif
        return FALSE;
        break;
    case 0:
        break;
    default:
        break;
    }

    ov_clear(&vfile);
    return TRUE;
}
Example #2
0
bool VorbisDecoderPlugin::canDecode(File* src) {
    OggVorbis_File vf;
    src->openRO();
    int r = ov_test_callbacks(src, &vf, 0, 0, _callbacks);
    ov_clear(&vf);
    src->close();
    return r==0;
}
Example #3
0
int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
  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
  };

  return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
Example #4
0
/**
 * @brief Loads the sound.
 *
 *    @param snd Sound to load.
 *    @param filename Name of the file to load into sound.
 */
int sound_al_load( alSound *snd, const char *filename )
{
   int ret;
   SDL_RWops *rw;
   OggVorbis_File vf;
   ALint freq, bits, channels, size;

   /* get the file data buffer from packfile */
   rw = ndata_rwops( filename );

   /* Check to see if it's an OGG. */
   if (ov_test_callbacks( rw, &vf, NULL, 0, sound_al_ovcall_noclose )==0) {
      ret = sound_al_loadOgg( snd, &vf );
   }
   /* Otherwise try WAV. */
   else {
      /* Destroy the partially loaded vorbisfile. */
      ov_clear(&vf);

      /* Try to load Wav. */
      ret = sound_al_loadWav( snd, rw );
   }

   /* Close RWops. */
   SDL_RWclose(rw);

   /* Failed to load. */
   if (ret != 0) {
      WARN("Failed to load sound file '%s'.", filename);
      return ret;
   }

   soundLock();

   /* Get the length of the sound. */
   alGetBufferi( snd->u.al.buf, AL_FREQUENCY, &freq );
   alGetBufferi( snd->u.al.buf, AL_BITS, &bits );
   alGetBufferi( snd->u.al.buf, AL_CHANNELS, &channels );
   alGetBufferi( snd->u.al.buf, AL_SIZE, &size );
   if ((freq==0) || (bits==0) || (channels==0)) {
      WARN("Something went wrong when loading sound file '%s'.", filename);
      snd->length = 0;
   }
   else
      snd->length = (double)size / (double)(freq * (bits/8) * channels);

   /* Check for errors. */
   al_checkErr();

   soundUnlock();

   return 0;
}
	bool OAOggVorbisReader::isValid(const SPtr<DataStream>& stream)
	{
		stream->seek(0);

		OggVorbis_File file;
		if (ov_test_callbacks(stream.get(), &file, nullptr, 0, callbacks) == 0)
		{
			ov_clear(&file);
			return true;
		}
			
		return false;
	}
	bool OggVorbisDecoder::isValid(const SPtr<DataStream>& stream, UINT32 offset)
	{
		stream->seek(offset);
		mDecoderData.stream = stream;
		mDecoderData.offset = offset;

		OggVorbis_File file;
		if (ov_test_callbacks(&mDecoderData, &file, nullptr, 0, callbacks) == 0)
		{
			ov_clear(&file);
			return true;
		}
			
		return false;
	}
Example #7
0
bool SndSysOggSoundData::IsOgg (iDataBuffer* Buffer)
{
  // This is a static function, no member variables are used
  OggDataStore datastore(Buffer);
  OggStreamData streamdata;

  streamdata.datastore=&datastore;
  streamdata.position=0;

  OggVorbis_File f;
  memset (&f, 0, sizeof(OggVorbis_File));
  bool ok = 
    ov_test_callbacks(&streamdata, &f, 0, 0, ogg_callbacks) == 0;
  ov_clear (&f);
  return ok;
}
bool VorbisDecoder::determineCodec( const char *data, size_t size )
{
	VorbisMemoryFile vorbisData;
	vorbisData.data = (char *)data;
	vorbisData.size = size;
	vorbisData.sizeRead = 0;

	OggVorbis_File vorbisFile;

	if( ov_test_callbacks( &vorbisData, &vorbisFile, 0x0, 0, vorbisCallbacks ) < 0 )
	{
		//it's not a vorbis file, clean up and return false
		ov_clear( &vorbisFile );
		return false;
	}

	ov_clear( &vorbisFile );
	return true;
}
Example #9
0
bool CSoundOgg::isOggFile(const std::string &name){
	CSoundOgg ogg;

	ogg.mFile = CFile(name);

	try {
		ogg.mFile.loadData();
	} catch (CException e) {
		return false;
	}

	ogg.mFileData = (char *)ogg.mFile.getData();
	ogg.mFilePos = 0;

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

	S32 res = ov_test_callbacks(&ogg, &ogg.mOggFile, 0, 0, cb);

	return res == 0 ? true : false;
}
Example #10
0
void Sound::Impl::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/) {
    if (!m_initialized || !GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled()))
        return;

    std::string filename = PathString(path);
    ALuint current_buffer;
    ALenum source_state;
    ALsizei ogg_freq;
    FILE *file = nullptr;
    int m_i;
    bool found_buffer = false;
    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()) {
        /* 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;
            found_buffer = true;
        } else {
            if ((file = fopen(filename.c_str(), "rb")) != nullptr) { // 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, nullptr, 0, callbacks))) // check if it's a proper ogg
#else
                if (!(ov_test(file, &ogg_file, nullptr, 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;
                        found_buffer = true;
                        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. */
    }
}
Example #11
0
void Sound::Impl::PlayMusic(const boost::filesystem::path& path, int loops /* = 0*/) {
    if (!m_initialized)
        return;

    ALenum m_openal_error;
    std::string filename = PathString(path);
    FILE* m_f = nullptr;
    vorbis_info* vorbis_info;
    m_music_loops = 0;

#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())
    {
        if (m_music_name.size() > 0)
            StopMusic();
       
        if ((m_f = fopen(filename.c_str(), "rb")) != nullptr) // make sure we CAN open it
        {
#ifdef FREEORION_WIN32
            if (!(ov_test_callbacks(m_f, &m_ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg
#else
            if (!(ov_test(m_f, &m_ogg_file, nullptr, 0))) // check if it's a proper ogg
#endif
            {
                ov_test_open(&m_ogg_file); // it is, now fully open the file
                /* now we need to take some info we will need later */
                vorbis_info = ov_info(&m_ogg_file, -1);
                if (vorbis_info->channels == 1)
                    m_ogg_format = AL_FORMAT_MONO16;
                else
                    m_ogg_format = AL_FORMAT_STEREO16;
                m_ogg_freq = vorbis_info->rate;
                m_music_loops = loops;
                /* fill up the buffers and queue them up for the first time */
                if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[0], BUFFER_SIZE, m_music_loops))
                {
                    alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[0]); // queue up the buffer if we manage to fill it
                    if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[1], BUFFER_SIZE, m_music_loops))
                    {
                        alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[1]);
                        m_music_name = filename; // yup, we're playing something that takes up more than 2 buffers
                    }
                    else
                    {
                        m_music_name.clear();  // m_music_name.clear() must always be called before ov_clear. Otherwise
                    }
                    alSourcePlay(m_sources[0]); // play if at least one buffer is queued
                }
                else
                {
                    m_music_name.clear();  // m_music_name.clear() must always be called before ov_clear. Otherwise
                }
            }
            else
            {
                ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n";
                m_music_name.clear(); //just in case
                ov_clear(&m_ogg_file);
            }
        }
        else
            ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " I/O Error. Aborting\n";
    }
    m_openal_error = alGetError();
    if (m_openal_error != AL_NONE)
        ErrorLogger() << "PlayMusic: OpenAL ERROR: " << alGetString(m_openal_error);
}
Example #12
0
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;
}
Example #13
0
void CreateVorbisStream(MFAudioStream *pStream, const char *pFilename)
{
	MFCALLSTACK;

	MFVorbisStream *pVS = (MFVorbisStream*)MFHeap_Alloc(sizeof(MFVorbisStream));
	pStream->pStreamData = pVS;

	// open vorbis file
	MFFile* hFile = MFFileSystem_Open(pFilename);
	if(!hFile)
		return;

	// attempt to cache the vorbis stream
	MFOpenDataCachedFile cachedOpen;
	cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
	cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
	cachedOpen.maxCacheSize = 256*1024; // 256k cache for vorbis stream should be heaps!!
	cachedOpen.pBaseFile = hFile;

	MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
	if(pCachedFile)
		hFile = pCachedFile;

	// setup vorbis read callbacks
	ov_callbacks callbacks;
	callbacks.read_func = MFFile_StdRead;
	callbacks.seek_func = MFSound_VorbisSeek;
	callbacks.close_func = MFFile_StdClose;
	callbacks.tell_func = MFFile_StdTell;

	// open vorbis file
	if(ov_test_callbacks(hFile, &pVS->vorbisFile, NULL, 0, callbacks))
	{
		MFDebug_Assert(false, "Not a vorbis file.");
		MFHeap_Free(pVS);
		return;
	}

	ov_test_open(&pVS->vorbisFile);

	// get vorbis file info
	pVS->pInfo = ov_info(&pVS->vorbisFile, -1);

#if defined(VORBIS_TREMOR)
//	pStream->trackLength = (float)ov_pcm_total(&pVS->vorbisFile, -1) / (float)pVS->pInfo->rate;
	pStream->trackLength = 1000.0f;
#else
	pStream->trackLength = (float)ov_time_total(&pVS->vorbisFile, -1);
#endif

	// fill out the stream info
	pStream->streamInfo.sampleRate = pVS->pInfo->rate;
	pStream->streamInfo.channels = pVS->pInfo->channels;
	pStream->streamInfo.bitsPerSample = 16;
	pStream->streamInfo.bufferLength = pVS->pInfo->rate;

	// read the vorbis comment data
	pVS->pComment = ov_comment(&pVS->vorbisFile, -1);
	if(pVS->pComment)
	{
		const char *pTitle = vorbis_comment_query(pVS->pComment, "TITLE", 0);
		const char *pArtist = vorbis_comment_query(pVS->pComment, "ALBUM", 0);
		const char *pAlbum = vorbis_comment_query(pVS->pComment, "ARTIST", 0);
		const char *pGenre = vorbis_comment_query(pVS->pComment, "GENRE", 0);

		if(pTitle)
			MFString_CopyN(pStream->streamInfo.songName, pTitle, sizeof(pStream->streamInfo.songName)-1);
		if(pArtist)
			MFString_CopyN(pStream->streamInfo.artistName, pArtist, sizeof(pStream->streamInfo.artistName)-1);
		if(pAlbum)
			MFString_CopyN(pStream->streamInfo.albumName, pAlbum, sizeof(pStream->streamInfo.albumName)-1);
		if(pGenre)
			MFString_CopyN(pStream->streamInfo.genre, pGenre, sizeof(pStream->streamInfo.genre)-1);
	}
}