示例#1
0
bool C4MusicFileOgg::Play(bool loop)
{
	// Load Song
	size_t iFileSize;
	if (!C4Group_ReadFile(FileName, &Data, &iFileSize))
		return false;

	// init fsound
	int loop_flag = loop ? FSOUND_LOOP_NORMAL : 0;
	stream = FSOUND_Stream_Open(Data, FSOUND_LOADMEMORY | FSOUND_NORMAL | FSOUND_2D | loop_flag, 0, iFileSize);

	if (!stream) return false;

	// Play Song
	Channel = FSOUND_Stream_Play(FSOUND_FREE, stream);
	if (Channel == -1) return false;

	// Set highest priority
	if (!FSOUND_SetPriority(Channel, 255))
		return false;

	Playing = true;

	FSOUND_Stream_SetEndCallback(stream, &C4MusicFileOgg::OnEnd, this);

	return true;
}
示例#2
0
bool C4MusicFileMP3::Play(bool loop)
{
#ifndef USE_MP3
	return false;
#endif

	// Load Song
	size_t iFileSize;
	if (!C4Group_ReadFile(FileName, &Data, &iFileSize))
		return false;

	// init fsound
	int loop_flag = loop ? FSOUND_LOOP_NORMAL : 0;
	stream = FSOUND_Stream_Open(Data, FSOUND_LOADMEMORY | FSOUND_NORMAL | FSOUND_2D | loop_flag, 0, iFileSize);

	if (!stream) return false;

	// Play Song
	Channel = FSOUND_Stream_Play(FSOUND_FREE, stream);
	if (Channel == -1) return false;

	// Set highest priority
	if (!FSOUND_SetPriority(Channel, 255))
		return false;

	return true;
}
示例#3
0
bool C4MusicFileSDL::Play(bool loop)
{
	const SDL_version * link_version = Mix_Linked_Version();
	if (link_version->major < 1
	    || (link_version->major == 1 && link_version->minor < 2)
	    || (link_version->major == 1 && link_version->minor == 2 && link_version->patch < 7))
	{
		// Check existance and try extracting it
		if (!FileExists(FileName)) if (!ExtractFile())
				// Doesn't exist - or file is corrupt
			{
				LogF("Error reading %s", FileName);
				return false;
			}
		// Load
		Music = Mix_LoadMUS(SongExtracted ? Config.AtTempPath(C4CFN_TempMusic2) : FileName);
		// Load failed
		if (!Music)
		{
			LogF("SDL_mixer: %s", SDL_GetError());
			return false;
		}
		// Play Song
		if (Mix_PlayMusic(Music, loop? -1 : 1) == -1)
		{
			LogF("SDL_mixer: %s", SDL_GetError());
			return false;
		}
	}
	else
	{
		// Load Song
		// Fixme: Try loading this from the group incrementally for less lag
		size_t filesize;
		if (!C4Group_ReadFile(FileName, &Data, &filesize))
		{
			LogF("Error reading %s", FileName);
			return false;
		}
		// Mix_FreeMusic frees the RWop
		Music = Mix_LoadMUS_RW(SDL_RWFromConstMem(Data, filesize));
		if (!Music)
		{
			LogF("SDL_mixer: %s", SDL_GetError());
			return false;
		}
		if (Mix_PlayMusic(Music, loop? -1 : 1) == -1)
		{
			LogF("SDL_mixer: %s", SDL_GetError());
			return false;
		}
	}
	return true;
}
示例#4
0
bool C4MusicFileMOD::Play(bool loop)
{
	// Load Song
	size_t iFileSize;
	if (!C4Group_ReadFile(FileName, &Data, &iFileSize))
		return false;

	// init fmusic
	mod = FMUSIC_LoadSongEx(Data, 0, iFileSize, FSOUND_LOADMEMORY, 0, 0);

	if (!mod)
	{
		LogF("FMod: %s", FMOD_ErrorString(FSOUND_GetError()));
		return false;
	}

	// Play Song
	FMUSIC_PlaySong(mod);

	return true;
}
示例#5
0
BOOL C4MusicFileMOD::Play(BOOL loop)
	{
	// Load Song
	size_t iFileSize;
	if(!C4Group_ReadFile(FileName, &Data, &iFileSize))
		return FALSE;

	// init fmusic
	mod = FMUSIC_LoadSongEx(Data, 0, iFileSize, FSOUND_LOADMEMORY, 0, 0);

	if (!mod) 
		{
		sprintf(OSTR, "FMod: %s", FMOD_ErrorString(FSOUND_GetError()));
	  Log(OSTR);
		return FALSE;
		}

	// Play Song
	FMUSIC_PlaySong(mod);

	return TRUE;
	}
示例#6
0
bool C4MusicFileOgg::Init(const char *strFile)
{
	// Clear previous
	Clear();
	// Base init file
	if (!C4MusicFile::Init(strFile)) return false;
	// Initial file loading
	// Currently, the whole compressed file is kept in memory because reading/seeking inside C4Group is problematic. Uncompress while playing.
	// This uses about 50MB of RAM (for ala's music pack) and increases startup time a bit.
	// Later, this could be replaced with proper random access in c4group. Either replacing the file format or e.g. storing the current zlib state here
	//  and then updating callbacks.read/seek/close/tell_func to read data from the group directly as needed
	char *file_contents;
	size_t file_size;
	if (!C4Group_ReadFile(FileName, &file_contents, &file_size))
		return false;
	data.SetOwnedData((BYTE *)file_contents, file_size);

	// Prepare ogg reader
	vorbis_info* info;
	memset(&ogg_file, 0, sizeof(ogg_file));
	ov_callbacks callbacks;
	callbacks.read_func = &::C4SoundLoaders::VorbisLoader::read_func;
	callbacks.seek_func = &::C4SoundLoaders::VorbisLoader::seek_func;
	callbacks.close_func = &::C4SoundLoaders::VorbisLoader::close_func;
	callbacks.tell_func = &::C4SoundLoaders::VorbisLoader::tell_func;

	// open using callbacks
	if (ov_open_callbacks(&data, &ogg_file, NULL, 0, callbacks) != 0)
	{
		ov_clear(&ogg_file);
		return false;
	}

	// get information about music
	info = ov_info(&ogg_file, -1);
	if (info->channels == 1)
		ogg_info.format = AL_FORMAT_MONO16;
	else
		ogg_info.format = AL_FORMAT_STEREO16;
	ogg_info.sample_rate = info->rate;
	ogg_info.sample_length = ov_time_total(&ogg_file, -1) / 1000.0;
	
	// Get categories from ogg comment header
	vorbis_comment *comment = ov_comment(&ogg_file, -1);
	const char *comment_id = "COMMENT=";
	int comment_id_len = strlen(comment_id);
	for (int i = 0; i < comment->comments; ++i)
	{
		if (comment->comment_lengths[i] > comment_id_len)
		{
			if (SEqual2NoCase(comment->user_comments[i], comment_id, comment_id_len))
			{
				// Add all categories delimeted by ';'
				const char *categories_string = comment->user_comments[i] + comment_id_len;
				for (;;)
				{
					int delimeter = SCharPos(';', categories_string);
					StdCopyStrBuf category;
					category.Copy(categories_string, delimeter >= 0 ? delimeter : SLen(categories_string));
					categories.push_back(category);
					if (delimeter < 0) break;
					categories_string += delimeter+1;
				}
			}
		}
	}

	// mark successfully loaded
	return loaded = true;
}