예제 #1
0
void USoundMod::Parse(class FAudioDevice* AudioDevice, const UPTRINT NodeWaveInstanceHash, FActiveSound& ActiveSound, const FSoundParseParameters& ParseParams, TArray<FWaveInstance*>& WaveInstances)
{
	FWaveInstance* WaveInstance = ActiveSound.FindWaveInstance(NodeWaveInstanceHash);

	// Create a new WaveInstance if this SoundWave doesn't already have one associated with it.
	if (WaveInstance == NULL)
	{
		const int32 SampleRate = 44100;

		// Create a new wave instance and associate with the ActiveSound
		WaveInstance = new FWaveInstance(&ActiveSound);
		WaveInstance->WaveInstanceHash = NodeWaveInstanceHash;
		ActiveSound.WaveInstances.Add(NodeWaveInstanceHash, WaveInstance);

		// Create streaming wave object
		USoundModWave* ModWave = NewObject<USoundModWave>();
		ModWave->SampleRate = SampleRate;
		ModWave->NumChannels = 2;
		ModWave->Duration = INDEFINITELY_LOOPING_DURATION;
		ModWave->bLooping = bLooping;

		if (ResourceData == NULL)
		{
			RawData.GetCopy((void**)&ResourceData, true);
		}

		ModWave->xmpContext = xmp_create_context();
		xmp_load_module_from_memory(ModWave->xmpContext, ResourceData, RawData.GetBulkDataSize());
		xmp_start_player(ModWave->xmpContext, SampleRate, 0);

		WaveInstance->WaveData = ModWave;
	}

	WaveInstance->WaveData->Parse(AudioDevice, NodeWaveInstanceHash, ActiveSound, ParseParams, WaveInstances);
}
예제 #2
0
static qboolean S_XMP_CodecOpenStream (snd_stream_t *stream)
{
/* need to load the whole file into memory and pass it to libxmp
 * using xmp_load_module_from_memory() which requires libxmp >= 4.2.
 * libxmp-4.0/4.1 only have xmp_load_module() which accepts a file
 * name which isn't good with files in containers like paks, etc. */
	xmp_context c;
	byte *moddata;
	long len;
	int mark;

	c = xmp_create_context();
	if (c == NULL)
		return false;

	len = FS_filelength (&stream->fh);
	mark = Hunk_LowMark();
	moddata = (byte *) Hunk_Alloc(len);
	FS_fread(moddata, 1, len, &stream->fh);
	if (xmp_load_module_from_memory(c, moddata, len) != 0)
	{
		Con_DPrintf("Could not load module %s\n", stream->name);
		goto err1;
	}

	Hunk_FreeToLowMark(mark); /* free original file data */
	stream->priv = c;
	if (shm->speed > XMP_MAX_SRATE)
		stream->info.rate = 44100;
	else if (shm->speed < XMP_MIN_SRATE)
		stream->info.rate = 11025;
	else	stream->info.rate = shm->speed;
	stream->info.bits = shm->samplebits;
	stream->info.width = stream->info.bits / 8;
	stream->info.channels = shm->channels;

	if (S_XMP_StartPlay(stream) != 0)
		goto err2;
	/* percentual left/right channel separation, default is 70. */
	if (stream->info.channels == 2)
		if (xmp_set_player(c, XMP_PLAYER_MIX, 100) != 0)
			goto err3;
	/* interpolation type, default is XMP_INTERP_LINEAR */
	if (xmp_set_player(c, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE) != 0)
		goto err3;

	return true;

err3:	xmp_end_player(c);
err2:	xmp_release_module(c);
err1:	xmp_free_context(c);
	return false;
}
예제 #3
0
파일: sound.cpp 프로젝트: przemub/openjazz
/**
 * Play music from the specified file.
 *
 * @param fileName Name of a file containing music data.
 */
void playMusic (const char * fileName) {

	File *file;
	unsigned char *psmData;
	int size;
	bool loadOk = false;

#ifdef USE_MODPLUG
	ModPlug_Settings settings;
#endif

	// Stop any existing music playing
	stopMusic();


	// Load the music file

	try {

		file = new File(fileName, false);

	} catch (int e) {

		return;

	}

	// Find the size of the file
	size = file->getSize();

	// Read the entire file into memory
	file->seek(0, true);
	psmData = file->loadBlock(size);

	delete file;


#ifdef USE_MODPLUG

	// Set up libmodplug

	settings.mFlags = MUSIC_FLAGS;
	settings.mChannels = audioSpec.channels;

	if ((audioSpec.format == AUDIO_U8) || (audioSpec.format == AUDIO_S8))
		settings.mBits = 8;
	else settings.mBits = 16;

	settings.mFrequency = audioSpec.freq;
	settings.mResamplingMode = MUSIC_RESAMPLEMODE;
	settings.mReverbDepth = 25;
	settings.mReverbDelay = 40;
	settings.mBassAmount = 50;
	settings.mBassRange = 10;
	settings.mSurroundDepth = 50;
	settings.mSurroundDelay = 40;
	settings.mLoopCount = -1;

	ModPlug_SetSettings(&settings);

	// Load the file into libmodplug
	musicFile = ModPlug_Load(psmData, size);
	loadOk = (musicFile != NULL);

#elif defined(USE_XMP)

	// Load the file into libxmp
	loadOk = (xmp_load_module_from_memory(xmpC, psmData, size) == 0);

#endif

	delete[] psmData;

	if (!loadOk) {

		logError("Could not play music file", fileName);

		return;

	}

#ifdef USE_XMP
	int playerFlags = 0;

	if ((audioSpec.format == AUDIO_U8) || (audioSpec.format == AUDIO_S8))
		playerFlags = playerFlags & XMP_FORMAT_8BIT;

	if ((audioSpec.format == AUDIO_U8) || (audioSpec.format == AUDIO_U16)
		|| (audioSpec.format == AUDIO_U16MSB) || (audioSpec.format == AUDIO_U16LSB))
		playerFlags = playerFlags & XMP_FORMAT_UNSIGNED;

	if (audioSpec.channels == 1)
		playerFlags = playerFlags & XMP_FORMAT_MONO;

	xmp_start_player(xmpC, audioSpec.freq, playerFlags);
	xmp_set_player(xmpC, XMP_PLAYER_INTERP, MUSIC_INTERPOLATION);
#  ifdef MUSIC_EFFECTS
	xmp_set_player(xmpC, XMP_PLAYER_DSP, MUSIC_EFFECTS);
#  endif

#endif

	// Start the audio playing
	SDL_PauseAudio(0);

	return;

}
예제 #4
0
UObject* USoundModImporterFactory::FactoryCreateBinary
(
	UClass*				Class,
	UObject*			InParent,
	FName				Name,
	EObjectFlags		Flags,
	UObject*			Context,
	const TCHAR*		FileType,
	const uint8*&		Buffer,
	const uint8*		BufferEnd,
	FFeedbackContext*	Warn
)
{
	// if the sound already exists, remember the user settings
	USoundMod* ExistingSound = FindObject<USoundMod>(InParent, *Name.ToString());

	// TODO - Audio Threading. This needs to be sent to the audio device and wait on stopping the sounds
	TArray<UAudioComponent*> ComponentsToRestart;
	FAudioDevice* AudioDevice = GEngine->GetAudioDevice();
	if (AudioDevice && ExistingSound)
	{
		// TODO: Generalize the stop sounds function
		//AudioDevice->StopSoundsForReimport(ExistingSound, ComponentsToRestart);
	}

	bool bUseExistingSettings = bSoundModFactorySuppressImportOverwriteDialog;

	if (ExistingSound && !bUseExistingSettings && !GIsAutomationTesting)
	{
		DisplayOverwriteOptionsDialog(FText::Format(
			NSLOCTEXT("SoundModImporterFactory", "ImportOverwriteWarning", "You are about to import '{0}' over an existing sound."),
			FText::FromName(Name)));

		switch (OverwriteYesOrNoToAllState)
		{
			case EAppReturnType::Yes:
			case EAppReturnType::YesAll:
			{
				// Overwrite existing settings
				bUseExistingSettings = false;
				break;
			}
			case EAppReturnType::No:
			case EAppReturnType::NoAll:
			{
				// Preserve existing settings
				bUseExistingSettings = true;
				break;
			}
			default:
			{
				FEditorDelegates::OnAssetPostImport.Broadcast(this, NULL);
				return NULL;
			}
		}
	}

	// Reset the flag back to false so subsequent imports are not suppressed unless the code explicitly suppresses it
	bSoundModFactorySuppressImportOverwriteDialog = false;

	TArray<uint8> RawModData;
	RawModData.Empty(BufferEnd - Buffer);
	RawModData.AddUninitialized(BufferEnd - Buffer);
	FMemory::Memcpy(RawModData.GetData(), Buffer, RawModData.Num());

	// TODO: Validate that this is actually a mod file
	xmp_context xmpContext = xmp_create_context();
	if (xmp_load_module_from_memory(xmpContext, RawModData.GetData(), RawModData.Num()) != 0)
	{
		return NULL;
	}
	xmp_module_info xmpModuleInfo;
	xmp_get_module_info(xmpContext, &xmpModuleInfo);

	// Use pre-existing sound if it exists and we want to keep settings,
	// otherwise create new sound and import raw data.
	USoundMod* Sound = (bUseExistingSettings && ExistingSound) ? ExistingSound : NewObject<USoundMod>(InParent, Name, Flags);

	Sound->Duration = xmpModuleInfo.seq_data->duration / 1000.f;

	xmp_release_module(xmpContext);
	xmp_free_context(xmpContext);

	Sound->RawData.Lock(LOCK_READ_WRITE);
	void* LockedData = Sound->RawData.Realloc(BufferEnd - Buffer);
	FMemory::Memcpy(LockedData, Buffer, BufferEnd - Buffer);
	Sound->RawData.Unlock();

	FEditorDelegates::OnAssetPostImport.Broadcast(this, Sound);

	for (int32 ComponentIndex = 0; ComponentIndex < ComponentsToRestart.Num(); ++ComponentIndex)
	{
		ComponentsToRestart[ComponentIndex]->Play();
	}

	return Sound;
}