[Scummvm-cvs-logs] SF.net SVN: scummvm:[51741] scummvm/trunk

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Wed Aug 4 18:53:09 CEST 2010


Revision: 51741
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51741&view=rev
Author:   athrxx
Date:     2010-08-04 16:53:09 +0000 (Wed, 04 Aug 2010)

Log Message:
-----------
AUDIO: Implement volume and balance control for the AudioCD manager (needed for music fading in Kyra 1 FM-Towns and probably other FM-Towns games). This addition applies to emulated CD audio only for now.  I haven't found a way to implement this for real CDs yet. SDL doesn't seem to support this (but it might be just me? If anyone knows more about this, just tell me).

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/sound_towns.cpp
    scummvm/trunk/sound/audiocd.cpp
    scummvm/trunk/sound/audiocd.h
    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp
    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h
    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.cpp
    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.h

Modified: scummvm/trunk/engines/kyra/sound_towns.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_towns.cpp	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/engines/kyra/sound_towns.cpp	2010-08-04 16:53:09 UTC (rev 51741)
@@ -66,6 +66,8 @@
 	if (!loadInstruments())
 		return false;
 
+	_driver->cdaSetVolume(1, 118, 118);
+
 	return true;
 }
 
@@ -90,6 +92,7 @@
 	beginFadeOut();
 
 	if (_musicEnabled == 2 && trackNum != -1) {
+		_driver->cdaSetVolume(1, 118, 118);
 		AudioCD.play(trackNum+1, loop ? -1 : 1, 0, 0);
 		AudioCD.updateCD();
 		_cdaPlaying = true;
@@ -198,7 +201,7 @@
 	}
 
 	_driver->chanVolume(_sfxChannel, 127);
-	_driver->chanStereo(_sfxChannel, 0x40);
+	_driver->chanPanPos(_sfxChannel, 0x40);
 	_driver->chanPitch(_sfxChannel, 0);
 	_driver->playSoundEffect(_sfxChannel, note, 127, sfxPlaybackBuffer);
 }

Modified: scummvm/trunk/sound/audiocd.cpp
===================================================================
--- scummvm/trunk/sound/audiocd.cpp	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/sound/audiocd.cpp	2010-08-04 16:53:09 UTC (rev 51741)
@@ -42,6 +42,8 @@
 	_cd.start = 0;
 	_cd.duration = 0;
 	_cd.numLoops = 0;
+	_cd.volume = Mixer::kMaxChannelVolume;
+	_cd.balance = 0;
 	_mixer = g_system->getMixer();
 	_emulating = false;
 	assert(_mixer);
@@ -79,7 +81,8 @@
 			*/
 			_emulating = true;
 			_mixer->playStream(Mixer::kMusicSoundType, &_handle,
-			                        makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
+			                        makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance);
+
 		} else {
 			_emulating = false;
 			if (!only_emulate)
@@ -109,6 +112,38 @@
 	}
 }
 
+void AudioCDManager::setVolume(byte volume) {
+	_cd.volume = volume;
+	if (_emulating) {
+		// Audio CD emulation
+		if (_mixer->isSoundHandleActive(_handle))
+			_mixer->setChannelVolume(_handle, _cd.volume);
+	} else {
+		// Real Audio CD
+		
+		// Unfortunately I can't implement this atm
+		// since SDL doesn't seem to offer an interface method for this.
+
+		// g_system->setVolumeCD(_cd.volume);
+	}
+}
+
+void AudioCDManager::setBalance(int8 balance) {
+	_cd.balance = balance;
+	if (_emulating) {
+		// Audio CD emulation
+		if (isPlaying())
+			_mixer->setChannelBalance(_handle, _cd.balance);
+	} else {
+		// Real Audio CD
+		
+		// Unfortunately I can't implement this atm
+		// since SDL doesn't seem to offer an interface method for this.
+
+		// g_system->setBalanceCD(_cd.balance);
+	}
+}
+
 void AudioCDManager::updateCD() {
 	if (_emulating) {
 		// Check whether the audio track stopped playback

Modified: scummvm/trunk/sound/audiocd.h
===================================================================
--- scummvm/trunk/sound/audiocd.h	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/sound/audiocd.h	2010-08-04 16:53:09 UTC (rev 51741)
@@ -42,6 +42,8 @@
 		int start;
 		int duration;
 		int numLoops;
+		int volume;
+		int balance;
 	};
 
 	/**
@@ -59,6 +61,9 @@
 	void stop();
 	bool isPlaying() const;
 
+	void setVolume(byte volume);
+	void setBalance(int8 balance);
+
 	void updateCD();
 
 	Status getStatus() const;

Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp
===================================================================
--- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp	2010-08-04 16:53:09 UTC (rev 51741)
@@ -24,6 +24,7 @@
  */
 
 #include "sound/softsynth/fmtowns_pc98/towns_audio.h"
+#include "sound/audiocd.h"
 #include "common/endian.h"
 
 
@@ -101,8 +102,9 @@
 
 TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns),
 	_fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),
-	_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), _pcmSfxChanMask(0),
-	_musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume), _ready(false) {
+	_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver),
+	_pcmSfxChanMask(0),	_musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
+	_cdaVolFlags(0), _ready(false) {
 
 #define INTCB(x) &TownsAudioInterface::intf_##x
 	static const TownsAudioIntfCallback intfCb[] = {
@@ -147,7 +149,7 @@
 		INTCB(notImpl),
 		INTCB(notImpl),
 		// 32
-		INTCB(notImpl),
+		INTCB(loadSamples),
 		INTCB(reserveEffectChannels),
 		INTCB(loadWaveTable),
 		INTCB(unloadWaveTable),
@@ -268,7 +270,6 @@
 		return 4;
 	}
 
-	Common::StackLock lock(_mutex);
 	int res = (this->*_intfOpcodes[command])(args);
 
 	va_end(args);
@@ -350,11 +351,9 @@
 
 void TownsAudioInterface::timerCallbackB() {
 	Common::StackLock lock(_mutex);
-	if (_ready) {
-		if (_drv)
-			_drv->timerCallback(1);
-		for (int i = 0; i < 8; i++)
-			pcmUpdateEnvelopeGenerator(i);
+	if (_drv && _ready) {
+		_drv->timerCallback(1);
+		callback(80);
 	}
 }
 
@@ -489,6 +488,29 @@
 	return 0;
 }
 
+int TownsAudioInterface::intf_loadSamples(va_list &args) {
+	uint32 dest = va_arg(args, uint32);
+	int size = va_arg(args, int);
+	uint8 *src = va_arg(args, uint8*);	
+
+	if (dest >= 65536 || size == 0 || size > 65536)
+		return 3;
+	if (size + dest > 65536)
+		return 5;
+
+	int dwIndex = _numWaveTables - 1;
+	for (uint32 t = _waveTablesTotalDataSize; dwIndex && (dest < t); dwIndex--)
+		t -= _waveTables[dwIndex].size;
+
+	TownsAudio_WaveTable *s = &_waveTables[dwIndex];
+	_waveTablesTotalDataSize -= s->size;
+	s->size = size;
+	s->readData(src);
+	_waveTablesTotalDataSize += s->size;
+
+	return 0;
+}
+
 int TownsAudioInterface::intf_reserveEffectChannels(va_list &args) {
 	int numChan = va_arg(args, int);
 	if (numChan > 8)
@@ -541,10 +563,10 @@
 
 	TownsAudio_WaveTable *s = &_waveTables[_numWaveTables++];
 	s->readHeader(data);
-	s->readData(data + 32);
+	
+	_waveTablesTotalDataSize += s->size;
+	callback(32, _waveTablesTotalDataSize, s->size, data + 32);
 
-	_waveTablesTotalDataSize += w.size;
-
 	return 0;
 }
 
@@ -698,9 +720,44 @@
 }
 
 int TownsAudioInterface::intf_cdaSetVolume(va_list &args) {
-	/*int unk = va_arg(args, int);
-	int volume1 = va_arg(args, int);
-	int volume2 = va_arg(args, int);*/
+	int mode = va_arg(args, int);
+	int left = va_arg(args, int);
+	int right = va_arg(args, int);
+
+	// calculate mixer balance value
+	int8 balance = right - left;
+
+	if (left & 0xff80 || right & 0xff80)
+		return 3;
+
+	static const uint8 flags[] = { 0x0C, 0x30, 0x40, 0x80 };
+
+	//int a = (mode & 0x40) ? 4 : 0;
+	int b = mode & 3;
+	left = (left & 0x7e) >> 1;
+	right = (right & 0x7e) >> 1;
+	
+	if (mode & 0x40)
+		_cdaVolFlags |= flags[b];
+	else
+		_cdaVolFlags &= ~flags[b];
+
+	if (mode > 1) {
+		// Unknown purpose / TODO
+
+	} else if (mode == 1) {
+		// FM Towns seems to support volumes of 0 - 63 for each channel.
+		// We recalculate sane values for out 0 to 255 volume range.
+
+		int vl = (int)(((float)left * 255.0f) / 63.0f);
+		int vr = (int)(((float)right * 255.0f) / 63.0f);
+		AudioCD.setVolume((vl + vr) >> 1);
+		AudioCD.setBalance(balance);
+
+	} else {
+		// Unknown purpose / TODO
+	}
+
 	return 0;
 }
 
@@ -1402,8 +1459,7 @@
 
 	panLeft = panRight = 0;
 
-	envTotalLevel = envAttackRate = envDecayRate = envSustainLevel =
-	                                    envSustainRate = envReleaseRate = 0;
+	envTotalLevel = envAttackRate = envDecayRate = envSustainLevel = envSustainRate = envReleaseRate = 0;
 	envStep = envCurrentLevel = 0;
 
 	envState = kEnvReady;

Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h
===================================================================
--- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h	2010-08-04 16:53:09 UTC (rev 51741)
@@ -77,6 +77,7 @@
 	int intf_setTimerB(va_list &args);
 	int intf_enableTimerA(va_list &args);
 	int intf_enableTimerB(va_list &args);
+	int intf_loadSamples(va_list &args);
 	int intf_reserveEffectChannels(va_list &args);
 	int intf_loadWaveTable(va_list &args);
 	int intf_unloadWaveTable(va_list &args);
@@ -148,6 +149,8 @@
 	void pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w);
 
 	void cdaReset();
+	
+	uint8 _cdaVolFlags;
 
 	const float _baserate;
 	uint32 _timerBase;

Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.cpp
===================================================================
--- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.cpp	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.cpp	2010-08-04 16:53:09 UTC (rev 51741)
@@ -66,8 +66,6 @@
 
 	reset();
 
-	cdaSetVolume(1, 118, 118);
-
 	return true;
 }
 
@@ -194,7 +192,7 @@
 	return _intf->callback(40, chan) ? true : false;
 }
 
-void TownsEuphonyDriver::chanStereo(int chan, int mode) {
+void TownsEuphonyDriver::chanPanPos(int chan, int mode) {
 	_intf->callback(3, chan, mode);
 }
 
@@ -206,8 +204,8 @@
 	_intf->callback(8, chan, vol);
 }
 
-void TownsEuphonyDriver::cdaSetVolume(int a, int vol1, int vol2) {
-	_intf->callback(67, a, vol1, vol2);
+void TownsEuphonyDriver::cdaSetVolume(int mode, int volLeft, int volRight) {
+	_intf->callback(67, mode, volLeft, volRight);
 }
 
 int TownsEuphonyDriver::chanEnable(int tableEntry, int val) {

Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.h
===================================================================
--- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.h	2010-08-04 16:13:26 UTC (rev 51740)
+++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_euphony.h	2010-08-04 16:53:09 UTC (rev 51741)
@@ -50,11 +50,11 @@
 	void stopSoundEffect(int chan);
 	bool soundEffectIsPlaying(int chan);
 
-	void chanStereo(int chan, int mode);
+	void chanPanPos(int chan, int mode);
 	void chanPitch(int chan, int pitch);
 	void chanVolume(int chan, int vol);
 
-	void cdaSetVolume(int a, int vol1, int vol2);
+	void cdaSetVolume(int mode, int volLeft, int volRight);
 
 	int chanEnable(int tableEntry, int val);
 	int chanMode(int tableEntry, int val);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list