Commits

spencercw committed abb4cb4

#22 Implement stereo output of sound channels.

Comments (0)

Files changed (2)

gb_emulator/include/gb_emulator/gb_sound.hpp

 	int16_t sound3();
 	int16_t 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);
+
 	// Sound callback which copies samples from soundBuf_ into the device buffer
 	static void soundCallback(void *userData, uint8_t *stream, int len);
 

gb_emulator/src/gb_sound.cpp

 	SDL_AudioSpec fmt, actFmt;
 	fmt.freq = 48000;
 	fmt.format = AUDIO_S16;
-	fmt.channels = 1;
+	fmt.channels = 2;
 	fmt.samples = 1024;
 	fmt.callback = soundCallback;
 	fmt.userdata = this;
 {
 	SdlAudioLock lock;
 	soundFile_.reset(new SndfileHandle(path.native().c_str(), SFM_WRITE,
-		SF_FORMAT_WAVEX | SF_FORMAT_PCM_16, 1, sampleRate_));
+		SF_FORMAT_WAVEX | SF_FORMAT_PCM_16, 2, sampleRate_));
 }
 
 void GbSound::stopRecording()
 	return amplitude;
 }
 
+void GbSound::doChannel(int16_t amplitude, uint8_t bit, int16_t &left, int16_t &right)
+{
+	if (gb_.mem_.ioPorts[NR51] & (bit << 4))
+	{
+		left += amplitude;
+	}
+	if (gb_.mem_.ioPorts[NR51] & bit)
+	{
+		right += amplitude;
+	}
+}
+
 void GbSound::soundCallback(void *userData, uint8_t *stream, int len)
 {
 	GbSound *parent = static_cast<GbSound *>(userData);
 
 	// Generate the audio
 	int16_t *actStream = reinterpret_cast<int16_t *>(stream);
-	for (int i = 0; i != len / 2; ++i)
+	for (int i = 0; i != len / 4; ++i)
 	{
-		int16_t amplitude = 0;
-		amplitude += parent->sound1();
-		amplitude += parent->sound2();
-		amplitude += parent->sound3();
-		amplitude += parent->sound4();
-		actStream[i] = amplitude;
+		int16_t 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);
+
+		actStream[2 * i] = left;
+		actStream[2 * i + 1] = right;
 	}
 
 	// Dump the audio if recording