| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-10 13:54:46 -05:00
										 |  |  | #pragma once
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-14 01:14:35 -04:00
										 |  |  | #include <mutex>
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "AudioCommon/WaveFile.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | // 16 bit Stereo
 | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | #define MAX_SAMPLES     (1024 * 2) // 64ms
 | 
					
						
							|  |  |  | #define INDEX_MASK      (MAX_SAMPLES * 2 - 1)
 | 
					
						
							| 
									
										
										
										
											2014-02-06 13:03:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | #define LOW_WATERMARK   1280 // 40 ms
 | 
					
						
							|  |  |  | #define MAX_FREQ_SHIFT  200  // per 32000 Hz
 | 
					
						
							| 
									
										
										
										
											2014-06-14 16:08:21 -07:00
										 |  |  | #define CONTROL_FACTOR  0.2f // in freq_shift per fifo size offset
 | 
					
						
							| 
									
										
										
										
											2014-02-16 15:30:18 -05:00
										 |  |  | #define CONTROL_AVG     32
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class CMixer { | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 	CMixer(unsigned int BackendSampleRate) | 
					
						
							|  |  |  | 		: m_dma_mixer(this, 32000) | 
					
						
							|  |  |  | 		, m_streaming_mixer(this, 48000) | 
					
						
							| 
									
										
										
										
											2014-09-05 22:32:48 +10:00
										 |  |  | 		, m_wiimote_speaker_mixer(this, 3000) | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 		, m_sampleRate(BackendSampleRate) | 
					
						
							| 
									
										
										
										
											2011-02-11 21:07:51 +00:00
										 |  |  | 		, m_logAudio(0) | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 		, m_speed(0) | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 		INFO_LOG(AUDIO_INTERFACE, "Mixer is initialized"); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-23 23:51:34 +00:00
										 |  |  | 	virtual ~CMixer() {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 	// Called from audio threads
 | 
					
						
							| 
									
										
										
										
											2014-02-13 13:22:29 +01:00
										 |  |  | 	virtual unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true); | 
					
						
							| 
									
										
										
										
											2009-12-20 02:23:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 	// Called from main thread
 | 
					
						
							| 
									
										
										
										
											2011-01-28 18:39:30 +00:00
										 |  |  | 	virtual void PushSamples(const short* samples, unsigned int num_samples); | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 	virtual void PushStreamingSamples(const short* samples, unsigned int num_samples); | 
					
						
							| 
									
										
										
										
											2014-09-06 01:23:54 +10:00
										 |  |  | 	virtual void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, unsigned int sample_rate); | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 	unsigned int GetSampleRate() const { return m_sampleRate; } | 
					
						
							| 
									
										
										
										
											2014-07-24 11:20:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	void SetDMAInputSampleRate(unsigned int rate); | 
					
						
							|  |  |  | 	void SetStreamInputSampleRate(unsigned int rate); | 
					
						
							| 
									
										
										
										
											2014-06-26 16:15:18 -07:00
										 |  |  | 	void SetStreamingVolume(unsigned int lvolume, unsigned int rvolume); | 
					
						
							| 
									
										
										
										
											2014-09-05 22:32:48 +10:00
										 |  |  | 	void SetWiimoteSpeakerVolume(unsigned int lvolume, unsigned int rvolume); | 
					
						
							| 
									
										
										
										
											2009-06-12 14:40:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 	virtual void StartLogAudio(const std::string& filename) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (! m_logAudio) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 			m_logAudio = true; | 
					
						
							| 
									
										
										
										
											2011-02-13 05:05:53 +00:00
										 |  |  | 			g_wave_writer.Start(filename, GetSampleRate()); | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 			g_wave_writer.SetSkipSilence(false); | 
					
						
							|  |  |  | 			NOTICE_LOG(DSPHLE, "Starting Audio logging"); | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-04-01 00:10:54 -04:00
										 |  |  | 			WARN_LOG(DSPHLE, "Audio logging has already been started"); | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 	virtual void StopLogAudio() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (m_logAudio) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 			m_logAudio = false; | 
					
						
							|  |  |  | 			g_wave_writer.Stop(); | 
					
						
							|  |  |  | 			NOTICE_LOG(DSPHLE, "Stopping Audio logging"); | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-04-01 00:10:54 -04:00
										 |  |  | 			WARN_LOG(DSPHLE, "Audio logging has already been stopped"); | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-30 20:16:12 -08:00
										 |  |  | 	std::mutex& MixerCritical() { return m_csMixing; } | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 	float GetCurrentSpeed() const { return m_speed; } | 
					
						
							| 
									
										
										
										
											2013-01-09 22:57:32 +11:00
										 |  |  | 	void UpdateSpeed(volatile float val) { m_speed = val; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 	class MixerFifo { | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 		MixerFifo(CMixer *mixer, unsigned sample_rate) | 
					
						
							|  |  |  | 			: m_mixer(mixer) | 
					
						
							|  |  |  | 			, m_input_sample_rate(sample_rate) | 
					
						
							|  |  |  | 			, m_indexW(0) | 
					
						
							|  |  |  | 			, m_indexR(0) | 
					
						
							| 
									
										
										
										
											2014-06-26 16:15:18 -07:00
										 |  |  | 			, m_LVolume(256) | 
					
						
							|  |  |  | 			, m_RVolume(256) | 
					
						
							| 
									
										
										
										
											2014-07-04 03:53:22 +02:00
										 |  |  | 			, m_numLeftI(0.0f) | 
					
						
							| 
									
										
										
										
											2014-07-17 18:26:21 +12:00
										 |  |  | 			, m_frac(0) | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			memset(m_buffer, 0, sizeof(m_buffer)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		void PushSamples(const short* samples, unsigned int num_samples); | 
					
						
							|  |  |  | 		unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true); | 
					
						
							| 
									
										
										
										
											2014-07-24 11:20:19 +08:00
										 |  |  | 		void SetInputSampleRate(unsigned int rate); | 
					
						
							| 
									
										
										
										
											2014-06-26 16:15:18 -07:00
										 |  |  | 		void SetVolume(unsigned int lvolume, unsigned int rvolume); | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 	private: | 
					
						
							|  |  |  | 		CMixer *m_mixer; | 
					
						
							|  |  |  | 		unsigned m_input_sample_rate; | 
					
						
							|  |  |  | 		short m_buffer[MAX_SAMPLES * 2]; | 
					
						
							|  |  |  | 		volatile u32 m_indexW; | 
					
						
							|  |  |  | 		volatile u32 m_indexR; | 
					
						
							| 
									
										
										
										
											2014-06-26 16:15:18 -07:00
										 |  |  | 		// Volume ranges from 0-256
 | 
					
						
							|  |  |  | 		volatile s32 m_LVolume; | 
					
						
							|  |  |  | 		volatile s32 m_RVolume; | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 		float m_numLeftI; | 
					
						
							| 
									
										
										
										
											2014-07-17 18:26:21 +12:00
										 |  |  | 		u32 m_frac; | 
					
						
							| 
									
										
										
										
											2014-04-10 18:28:19 -07:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 	MixerFifo m_dma_mixer; | 
					
						
							|  |  |  | 	MixerFifo m_streaming_mixer; | 
					
						
							| 
									
										
										
										
											2014-09-05 22:32:48 +10:00
										 |  |  | 	MixerFifo m_wiimote_speaker_mixer; | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	unsigned int m_sampleRate; | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	WaveFileWriter g_wave_writer; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 	bool m_logAudio; | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-30 20:16:12 -08:00
										 |  |  | 	std::mutex m_csMixing; | 
					
						
							| 
									
										
										
										
											2013-01-09 22:57:32 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	volatile float m_speed; // Current rate of the emulation (1.0 = 100% speed)
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | }; |