| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2009-01-17 14:28:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | #include "Atomic.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | #include "Mixer.h"
 | 
					
						
							| 
									
										
										
										
											2009-03-26 09:29:14 +00:00
										 |  |  | #include "AudioCommon.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | #include "CPUDetect.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-07 15:14:29 -05:00
										 |  |  | #include "../Core/Host.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-07 15:14:29 -05:00
										 |  |  | #include "../Core/HW/AudioInterface.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-28 18:39:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // UGLINESS
 | 
					
						
							| 
									
										
										
										
											2013-12-07 15:14:29 -05:00
										 |  |  | #include "../Core/PowerPC/PowerPC.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-28 18:39:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-12 09:34:53 +00:00
										 |  |  | #if _M_SSE >= 0x301 && !(defined __GNUC__ && !defined __SSSE3__)
 | 
					
						
							|  |  |  | #include <tmmintrin.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | // Executed from sound stream thread
 | 
					
						
							|  |  |  | unsigned int CMixer::Mix(short* samples, unsigned int numSamples) | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	if (!samples) | 
					
						
							| 
									
										
										
										
											2009-06-12 14:40:50 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-30 20:16:12 -08:00
										 |  |  | 	std::lock_guard<std::mutex> lk(m_csMixing); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (PowerPC::GetState() != PowerPC::CPU_RUNNING) | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-01-28 18:39:30 +00:00
										 |  |  | 		// Silence
 | 
					
						
							|  |  |  | 		memset(samples, 0, numSamples * 4); | 
					
						
							|  |  |  | 		return numSamples; | 
					
						
							| 
									
										
										
										
											2009-03-30 09:55:50 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	unsigned int numLeft = GetNumSamples(); | 
					
						
							| 
									
										
										
										
											2010-10-01 23:23:13 +00:00
										 |  |  | 	if (m_AIplaying) { | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		if (numLeft < numSamples)//cannot do much about this
 | 
					
						
							| 
									
										
										
										
											2010-10-01 23:23:13 +00:00
										 |  |  | 			m_AIplaying = false; | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		if (numLeft < MAX_SAMPLES/4)//low watermark
 | 
					
						
							| 
									
										
										
										
											2010-10-01 23:23:13 +00:00
										 |  |  | 			m_AIplaying = false; | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		if (numLeft > MAX_SAMPLES/2)//high watermark
 | 
					
						
							| 
									
										
										
										
											2010-10-01 23:23:13 +00:00
										 |  |  | 			m_AIplaying = true; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	// Cache access in non-volatile variable
 | 
					
						
							|  |  |  | 	// This is the only function changing the read value, so it's safe to
 | 
					
						
							|  |  |  | 	// cache it locally although it's written here.
 | 
					
						
							|  |  |  | 	// The writing pointer will be modified outside, but it will only increase,
 | 
					
						
							|  |  |  | 	// so we will just ignore new written data while interpolating.
 | 
					
						
							|  |  |  | 	// Without this cache, the compiler wouldn't be allowed to optimize the
 | 
					
						
							|  |  |  | 	// interpolation loop.
 | 
					
						
							|  |  |  | 	u32 indexR = Common::AtomicLoad(m_indexR); | 
					
						
							|  |  |  | 	u32 indexW = Common::AtomicLoad(m_indexW); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 23:23:13 +00:00
										 |  |  | 	if (m_AIplaying) { | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		numLeft = (numLeft > numSamples) ? numSamples : numLeft; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-05 14:53:00 +00:00
										 |  |  | 		if (AudioInterface::GetAIDSampleRate() == m_sampleRate) // (1:1)
 | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | #if _M_SSE >= 0x301
 | 
					
						
							|  |  |  | 			if (cpu_info.bSSSE3 && !((numLeft * 2) % 8)) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-03-12 22:02:46 +00:00
										 |  |  | 				static const __m128i sr_mask = | 
					
						
							|  |  |  | 					_mm_set_epi32(0x0C0D0E0FL, 0x08090A0BL, | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 								  0x04050607L, 0x00010203L); | 
					
						
							| 
									
										
										
										
											2011-03-12 22:02:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | 				for (unsigned int i = 0; i < numLeft * 2; i += 8) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 					_mm_storeu_si128((__m128i *)&samples[i], _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)&m_buffer[(indexR + i) & INDEX_MASK]), sr_mask)); | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-01-12 21:21:15 +00:00
										 |  |  | 				for (unsigned int i = 0; i < numLeft * 2; i+=2) | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 					samples[i] = Common::swap16(m_buffer[(indexR + i + 1) & INDEX_MASK]); | 
					
						
							|  |  |  | 					samples[i+1] = Common::swap16(m_buffer[(indexR + i) & INDEX_MASK]); | 
					
						
							| 
									
										
										
										
											2011-01-12 07:08:35 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 			indexR += numLeft * 2; | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 		else //linear interpolation
 | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 			//render numleft sample pairs to samples[]
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 			//advance indexR with sample position
 | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 			//remember fractional offset
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			static u32 frac = 0; | 
					
						
							| 
									
										
										
										
											2011-05-05 14:53:00 +00:00
										 |  |  | 			const u32 ratio = (u32)( 65536.0f * (float)AudioInterface::GetAIDSampleRate() / (float)m_sampleRate ); | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for (u32 i = 0; i < numLeft * 2; i+=2) { | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 				u32 indexR2 = indexR + 2; //next sample
 | 
					
						
							|  |  |  | 				if ((indexR2 & INDEX_MASK) == (indexW & INDEX_MASK)) //..if it exists
 | 
					
						
							|  |  |  | 					indexR2 = indexR; | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 				s16 l1 = Common::swap16(m_buffer[indexR & INDEX_MASK]); //current
 | 
					
						
							|  |  |  | 				s16 l2 = Common::swap16(m_buffer[indexR2 & INDEX_MASK]); //next
 | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 				int sampleL = ((l1 << 16) + (l2 - l1) * (u16)frac)  >> 16; | 
					
						
							|  |  |  | 				samples[i+1] = sampleL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 				s16 r1 = Common::swap16(m_buffer[(indexR + 1) & INDEX_MASK]); //current
 | 
					
						
							|  |  |  | 				s16 r2 = Common::swap16(m_buffer[(indexR2 + 1) & INDEX_MASK]); //next
 | 
					
						
							| 
									
										
										
										
											2010-11-12 05:05:27 +00:00
										 |  |  | 				int sampleR = ((r1 << 16) + (r2 - r1) * (u16)frac)  >> 16; | 
					
						
							| 
									
										
										
										
											2011-01-12 21:21:15 +00:00
										 |  |  | 				samples[i] = sampleR; | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				frac += ratio; | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 				indexR += 2 * (u16)(frac >> 16); | 
					
						
							| 
									
										
										
										
											2010-11-12 03:39:07 +00:00
										 |  |  | 				frac &= 0xffff; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-09-28 21:43:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		numLeft = 0; | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-22 07:26:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	// Padding
 | 
					
						
							|  |  |  | 	if (numSamples > numLeft) | 
					
						
							| 
									
										
										
										
											2011-03-12 22:02:46 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		unsigned short s[2]; | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 		s[0] = Common::swap16(m_buffer[(indexR - 1) & INDEX_MASK]); | 
					
						
							|  |  |  | 		s[1] = Common::swap16(m_buffer[(indexR - 2) & INDEX_MASK]); | 
					
						
							| 
									
										
										
										
											2011-03-12 22:02:46 +00:00
										 |  |  | 		for (unsigned int i = numLeft*2; i < numSamples*2; i+=2) | 
					
						
							|  |  |  | 			*(u32*)(samples+i) = *(u32*)(s); | 
					
						
							|  |  |  | //		memset(&samples[numLeft * 2], 0, (numSamples - numLeft) * 4);
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Flush cached variable
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	Common::AtomicStore(m_indexR, indexR); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 	//when logging, also throttle HLE audio
 | 
					
						
							|  |  |  | 	if (m_logAudio) { | 
					
						
							|  |  |  | 		if (m_AIplaying) { | 
					
						
							|  |  |  | 			Premix(samples, numLeft); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-23 05:02:43 +10:00
										 |  |  | 			AudioInterface::Callback_GetStreaming(samples, numLeft, m_sampleRate); | 
					
						
							| 
									
										
										
										
											2011-02-11 18:59:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			g_wave_writer.AddStereoSamples(samples, numLeft); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { 	//or mix as usual
 | 
					
						
							|  |  |  | 		// Add the DSPHLE sound, re-sampling is done inside
 | 
					
						
							|  |  |  | 		Premix(samples, numSamples); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Add the DTK Music
 | 
					
						
							| 
									
										
										
										
											2012-04-23 05:02:43 +10:00
										 |  |  | 		// Re-sampling is done inside
 | 
					
						
							|  |  |  | 		AudioInterface::Callback_GetStreaming(samples, numSamples, m_sampleRate); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return numSamples; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-28 18:39:30 +00:00
										 |  |  | void CMixer::PushSamples(const short *samples, unsigned int num_samples) | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	// Cache access in non-volatile variable
 | 
					
						
							|  |  |  | 	// indexR isn't allowed to cache in the audio throttling loop as it
 | 
					
						
							|  |  |  | 	// needs to get updates to not deadlock.
 | 
					
						
							|  |  |  | 	u32 indexW = Common::AtomicLoad(m_indexW); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-17 15:45:12 +00:00
										 |  |  | 	if (m_throttle) | 
					
						
							| 
									
										
										
											
												Hy, this is my first commit, and i hope it is not bad xD. 
- First change is for Mixer.cpp, I've just re-added the functionality lost in r4724, so, if you disable audio throttle, games like donkey kong jungle beat, will work properly.
- Second change points to a doubt comment on UCode_Zelda_Voice.cpp, where it did not know here PB.NeedsReset came from. Well, the answer is it came from line 03b2 of the dumped Ucode, so when PB.IsBlanck equals to zero, PB.NeedsReset is zero too.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6100 8ced0084-cf51-0410-be5f-012b33b47a6e
											
										 
											2010-08-16 15:22:53 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// The auto throttle function. This loop will put a ceiling on the CPU MHz.
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 		while (num_samples * 2 + ((indexW - Common::AtomicLoad(m_indexR)) & INDEX_MASK) >= MAX_SAMPLES * 2) | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 			if (*PowerPC::GetStatePtr() != PowerPC::CPU_RUNNING || soundStream->IsMuted()) | 
					
						
							| 
									
										
										
										
											2011-01-28 18:39:30 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-12-25 11:59:04 +00:00
										 |  |  | 			// Shortcut key for Throttle Skipping
 | 
					
						
							| 
									
										
										
										
											2011-01-30 16:40:38 +00:00
										 |  |  | 			if (Host_GetKeyState('\t')) | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 			SLEEP(1); | 
					
						
							| 
									
										
										
										
											2009-12-25 11:59:04 +00:00
										 |  |  | 			soundStream->Update(); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check if we have enough free space
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	// indexW == m_indexR results in empty buffer, so indexR must always be smaller than indexW
 | 
					
						
							|  |  |  | 	if (num_samples * 2 + ((indexW - Common::AtomicLoad(m_indexR)) & INDEX_MASK) >= MAX_SAMPLES * 2) | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// AyuanX: Actual re-sampling work has been moved to sound thread
 | 
					
						
							| 
									
										
										
										
											2009-12-25 11:59:04 +00:00
										 |  |  | 	// to alleviate the workload on main thread
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	// and we simply store raw data here to make fast mem copy
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	int over_bytes = num_samples * 4 - (MAX_SAMPLES * 2 - (indexW & INDEX_MASK)) * sizeof(short); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	if (over_bytes > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 		memcpy(&m_buffer[indexW & INDEX_MASK], samples, num_samples * 4 - over_bytes); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 		memcpy(&m_buffer[0], samples + (num_samples * 4 - over_bytes) / sizeof(short), over_bytes); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 		memcpy(&m_buffer[indexW & INDEX_MASK], samples, num_samples * 4); | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	Common::AtomicAdd(m_indexW, num_samples * 2); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | 	return; | 
					
						
							| 
									
										
										
										
											2008-12-08 05:25:12 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-12-20 02:23:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-23 15:34:14 +00:00
										 |  |  | unsigned int CMixer::GetNumSamples() | 
					
						
							| 
									
										
										
										
											2009-12-20 02:23:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	// Guess how many samples would be available after interpolation.
 | 
					
						
							|  |  |  | 	// As interpolation needs at least on sample from the future to
 | 
					
						
							|  |  |  | 	// linear interpolate between them, one sample less is available.
 | 
					
						
							|  |  |  | 	// We also can't say the current interpolation state (specially
 | 
					
						
							|  |  |  | 	// the frac), so to be sure, subtract one again to be sure not
 | 
					
						
							|  |  |  | 	// to underflow the fifo.
 | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	u32 numSamples = ((Common::AtomicLoad(m_indexW) - Common::AtomicLoad(m_indexR)) & INDEX_MASK) / 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (AudioInterface::GetAIDSampleRate() == m_sampleRate) | 
					
						
							| 
									
										
										
										
											2013-08-29 01:33:24 -04:00
										 |  |  | 		; //numSamples = numSamples; // 1:1
 | 
					
						
							| 
									
										
										
										
											2013-07-11 21:22:38 +02:00
										 |  |  | 	else if (m_sampleRate == 48000 && AudioInterface::GetAIDSampleRate() == 32000) | 
					
						
							|  |  |  | 		numSamples = numSamples * 3 / 2 - 2; // most common case
 | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		numSamples = numSamples * m_sampleRate / AudioInterface::GetAIDSampleRate() - 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return numSamples; | 
					
						
							| 
									
										
										
										
											2009-12-20 02:23:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 |