Commits

spencercw  committed e2c742a

# 24 Implement the volume control from register NR50.

  • Participants
  • Parent commits abb4cb4

Comments (0)

Files changed (2)

File gb_emulator/include/gb_emulator/gb_sound.hpp

 	unsigned counterIndex4_;
 
 	// Functions for each of the sound modes. The output is mixed in the main poll() function
-	int16_t sound1();
-	int16_t sound2();
-	int16_t sound3();
-	int16_t sound4();
+	double sound1();
+	double sound2();
+	double sound3();
+	double sound4();
 
 	// Adds the given channel amplitude to the appropriate output channels based on the value of the
 	// control bits
-	void doChannel(int16_t amplitude, uint8_t bit, int16_t &left, int16_t &right);
+	void doChannel(double amplitude, uint8_t bit, double &left, double &right);
 
 	// Sound callback which copies samples from soundBuf_ into the device buffer
 	static void soundCallback(void *userData, uint8_t *stream, int len);

File gb_emulator/src/gb_sound.cpp

 	soundFile_.reset();
 }
 
-int16_t GbSound::sound1()
+double GbSound::sound1()
 {
 	if (countdown1_ <= 0)
 	{
 		}
 	}
 
-	int16_t amplitude = 0x1000;
-	amplitude = static_cast<int16_t>(amplitude * (envelope1_ / 15.));
+	double amplitude = 0x200;
+	amplitude = amplitude * (envelope1_ / 15.);
 
 	// Handle the frequency sweep
 	if (sweepStep_ && --sweepCountdown_ <= 0)
 	return hi1_ ? amplitude : -amplitude;
 }
 
-int16_t GbSound::sound2()
+double GbSound::sound2()
 {
 	if (countdown2_ <= 0)
 	{
 		}
 	}
 
-	int16_t amplitude = 0x1000;
-	amplitude = static_cast<int16_t>(amplitude * (envelope2_ / 15.));
+	double amplitude = 0x200;
+	amplitude = amplitude * (envelope2_ / 15.);
 
 	// Handle the envelope step
 	if (envelope2_ && envelopeStep2_)
 	return hi2_ ? amplitude : -amplitude;
 }
 
-int16_t GbSound::sound3()
+double GbSound::sound3()
 {
 	if (countdown3_ <= 0)
 	{
 		duration3_  -= 1 / actFrequency3_ / 16 * sampleRate_;
 	}
 
-	int16_t amplitude;
+	double amplitude;
 	if (!(gb_.mem_.ioPorts[NR51] & 0x44))
 	{
 		gb_.mem_.ioPorts[NR52] &= ~0x04;
 		// Shift right to adjust the output level
 		sample >>= outLevel3_;
 
-		amplitude = static_cast<int16_t>(0x1000 * ((sample - 7.5) / 7.5));
+		amplitude = 0x200 * ((sample - 7.5) / 7.5);
 	}
 
 	--countdown3_;
 	return amplitude;
 }
 
-int16_t GbSound::sound4()
+double GbSound::sound4()
 {
 	// Return silence if nothing is playing and nothing is set to play
 	if (countdown4_ <= 0 && !(gb_.mem_.ioPorts[NR52] & 0x08) && !(gb_.mem_.ioPorts[NR44] & 0x80))
 	unsigned index = counterIndex4_ / 32;
 	uint32_t bit = 1 << (counterIndex4_ % 32);
 
-	static const int16_t amplitudes[] = { -0x1000, 0x1000 };
+	static const double amplitudes[] = { -0x200, 0x200 };
 	bool val = (counterData4_[index] & bit) == bit;
-	int16_t amplitude = static_cast<int16_t>(amplitudes[val] * (envelope4_ / 15.));
+	double amplitude = amplitudes[val] * (envelope4_ / 15.);
 
 	// Handle the envelope step
 	if (envelopeStep4_ &&
 	return amplitude;
 }
 
-void GbSound::doChannel(int16_t amplitude, uint8_t bit, int16_t &left, int16_t &right)
+void GbSound::doChannel(double amplitude, uint8_t bit, double &left, double &right)
 {
 	if (gb_.mem_.ioPorts[NR51] & (bit << 4))
 	{
 	int16_t *actStream = reinterpret_cast<int16_t *>(stream);
 	for (int i = 0; i != len / 4; ++i)
 	{
-		int16_t left = 0, right = 0;
+		double left = 0, right = 0;
 		parent->doChannel(parent->sound1(), 1, left, right);
 		parent->doChannel(parent->sound2(), 2, left, right);
 		parent->doChannel(parent->sound3(), 4, left, right);
 		parent->doChannel(parent->sound4(), 8, left, right);
+		
+		left  += left  *  (parent->gb_.mem_.ioPorts[NR50] & 0x07);
+		right += right * ((parent->gb_.mem_.ioPorts[NR50] & 0x70) >> 4);
 
-		actStream[2 * i] = left;
-		actStream[2 * i + 1] = right;
+		actStream[2 * i] =     static_cast<int16_t>(left);
+		actStream[2 * i + 1] = static_cast<int16_t>(right);
 	}
 
 	// Dump the audio if recording