view src/audio/symbian/streamplayer.cpp @ 4389:c6c3a6e7db46 SDL-1.2

Fixed bug #899 Jeremiah Morris 2009-12-09 16:23:50 PST Re-enable mouseLocation workaround on 10.4, 10.5 OS X systems before 10.6 have a bug with [NSEvent mouseLocation] if the screen resolution changes. SDL_QuartzVideo.m contains a workaround for this bug, but it was placed inside an #ifdef in revision 4762. The comment reads, "I'm gambling they fixed this by 10.4." After seeing this bug on several Tiger and Leopard systems (both PPC and Intel), I can confirm that it's not fixed until 10.6. The workaround doesn't compile for x86_64/10.6, so I can understand why it was segregated, but it needs to remain in place for the i386 and ppc versions. The workaround causes no problems under 10.6, even though it's not necessary there. Patch is attached with one method of keeping the workaround active on the systems that need it.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 11 Dec 2009 15:11:49 +0000
parents e85e65aec22f
children
line wrap: on
line source

#include "streamplayer.h"
#include<mda/common/audio.h>



const TInt KMaxVolume(256);

LOCAL_C TInt GetSampleRate(TInt aRate)
    {
    switch(aRate)
        {
        case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz;
        case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz;
        case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz;
        case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz;
        case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz;
        case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz;
        case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz;
        case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz;
        case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz;
        case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz;
        case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz;
        }
    return KErrNotFound;
    }

LOCAL_C TInt GetChannels(TInt aChannels)
    {
    switch(aChannels)
        {
        case 1: return TMdaAudioDataSettings::EChannelsMono;
        case 2: return TMdaAudioDataSettings::EChannelsStereo;
        }
    return KErrNotFound;
    }
    
TInt CStreamPlayer::ClosestSupportedRate(TInt aRate)
	{
	if(aRate > 96000)
		return 96000;
	TInt rate = aRate;
	while(GetSampleRate(rate) == KErrNotFound)
		{
		++rate;
		}
	return rate;
	}

CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider,  MStreamObs& aObs) :
 iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume)
	{	
	}
		
CStreamPlayer::~CStreamPlayer()
	{
	iState |= EDied;
	if(iState & EInited)
		Close();
	User::After(100000); //wait buffer to be flushed
	ASSERT(iPtr.Length() == 0);
	delete iStream;
	}
		
		
void CStreamPlayer::ConstructL()
	{
	iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax);
	iSilence.SetMax();
	iSilence.FillZ();
	}
		

TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType)
	{
	Close();
	
	iType = aType;
	
	iRate = GetSampleRate(aRate);
	if(iRate == KErrNotFound)
		return KErrNotSupported;
	
	iChannels = GetChannels(aChannels);
	if(iChannels == KErrNotFound)
		return KErrNotSupported;
	
	Open();
    
    return KErrNone;
	}


TInt CStreamPlayer::MaxVolume() const
	{
	return KMaxVolume;
	}

void CStreamPlayer::SetVolume(TInt aNew)
    {
    
    const TInt maxi = MaxVolume();
    if(aNew > maxi)
		return;
    if(aNew < 0)
    	return;
    
    iVolume = aNew;
    
    iState |= EVolumeChange;
    }
    
 TInt CStreamPlayer::Volume() const
    {
	return iVolume;
    }

void CStreamPlayer::Open()
	{
	TMdaAudioDataSettings audioSettings;
	audioSettings.Query();
    audioSettings.iCaps = TMdaAudioDataSettings::ERealTime |
     	TMdaAudioDataSettings::ESampleRateFixed; 
    audioSettings.iSampleRate = iRate; 
    audioSettings.iChannels = iChannels;
	audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting;
	audioSettings.iVolume = 0;
	
	iState &= ~EStopped;
    iStream->Open(&audioSettings);    
	}
	
void CStreamPlayer::Stop()
	{
	if(iState & (EStarted | EInited))
		{
		Close();
		iState |= EStopped;
		}
	}
	
void CStreamPlayer::Start()
	{
	if(iPtr.Length() == 0)
		{
		iState |= EStarted;
		if(iState & EInited)
			{
			Request();
			}
		else if(iState & EStopped)
			{
			Open();
			}
		}
	}

void CStreamPlayer::Close()
	{
	iState &= ~EInited;
	iStream->Stop();
	iState &= ~EStarted;
	}
	
void CStreamPlayer::Request()
	{
	if(iState & EInited)
		{
		iPtr.Set(KNullDesC8);
		
		if(iState & EVolumeChange)
			{
       		const TReal newVol = iVolume;
       		const TReal newMax = MaxVolume();
       		const TInt maxVol = iStream->MaxVolume();
       		const TReal max = static_cast<TReal>(maxVol);
       		const TReal newvolume = (newVol * max) / newMax;
       		const TInt vol = static_cast<TReal>(newvolume);
       		iStream->SetVolume(vol);
			iState &= ~EVolumeChange;
			}
			
		if(iState & EStarted)
			{
	 		iPtr.Set(iProvider.Data());
			}
		if(iPtr.Length() == 0)
			{
			iPtr.Set(iSilence);
			}
		TRAPD(err, iStream->WriteL(iPtr));
		if(err != KErrNone)
			{
			iObs.Complete(MStreamObs::EWrite, err);	
			}
	/*	else
			{
			iProvider.Written(iPtr.Length());
			}*/
		}
	}
	

void CStreamPlayer::SetCapsL()
	{
	iStream->SetDataTypeL(iType);
	iStream->SetAudioPropertiesL(iRate, iChannels);
	}

void CStreamPlayer::MaoscOpenComplete(TInt aError) 
	{
	if(aError == KErrNone)
		{
		TRAPD(err, SetCapsL());
    	if(err == KErrNone)
    		{
    		iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime);
    		iState |= EInited;
    		
    		
        	SetVolume(Volume());	
    		
    		if(iState & EStarted)
    			{
    			Request();
    			}
    			
			}
		aError = err;
		}
	if(!(iState & EDied))
		iObs.Complete(MStreamObs::EInit, aError);
	}
	
void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
	{
	iPtr.Set(KNullDesC8);
	if(aError == KErrNone)
		{
		if(iState & EInited)
			Request();
		else
			iStream->Stop();
		}
	else if(!(iState & EDied))
		iObs.Complete(MStreamObs::EPlay, aError);
	}
	
void CStreamPlayer::MaoscPlayComplete(TInt aError)
	{	
	iPtr.Set(KNullDesC8);
	iState &= ~EStarted;
	if(!(iState & EDied))
		iObs.Complete(MStreamObs::EClose, aError);
	}
	
TBool CStreamPlayer::Playing() const
	{
	return (iState & EInited) && (iState & EStarted);
	}

TBool CStreamPlayer::Closed() const
	{
	return !(iState & EInited) && !(iState & EDied);
	}
	
	/*
void CStreamPlayer::Request()
	{
	SetActive();
	TRequestStatus* s = &iStatus;
	User::RequestComplete(s, KErrNone);
	}
	//		iTimer.After(0);
	*/