Cocoa Port: Refactor the hardware mic stuff out of CocoaDSController and into ClientInputHandler.
This commit is contained in:
parent
f8bbbec0ae
commit
f521ab1164
|
@ -73,7 +73,14 @@ ClientInputHandler::ClientInputHandler()
|
||||||
_internalNoiseGenerator = new InternalNoiseGenerator;
|
_internalNoiseGenerator = new InternalNoiseGenerator;
|
||||||
_whiteNoiseGenerator = new WhiteNoiseGenerator;
|
_whiteNoiseGenerator = new WhiteNoiseGenerator;
|
||||||
_sineWaveGenerator = new SineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
_sineWaveGenerator = new SineWaveGenerator(250.0, MIC_SAMPLE_RATE);
|
||||||
_selectedAudioFileGenerator = NULL;
|
_selectedAudioFileGenerator = NULL; // Note that this value can be NULL.
|
||||||
|
_hardwareMicSampleGenerator = _nullSampleGenerator;
|
||||||
|
|
||||||
|
_avgMicLevel = 0.0f;
|
||||||
|
_avgMicLevelTotal = 0.0f;
|
||||||
|
_avgMicLevelsRead = 0.0f;
|
||||||
|
_isHardwareMicMuted = true;
|
||||||
|
_isHardwareMicPaused = true;
|
||||||
|
|
||||||
_enableAutohold = false;
|
_enableAutohold = false;
|
||||||
|
|
||||||
|
@ -83,7 +90,9 @@ ClientInputHandler::ClientInputHandler()
|
||||||
_paddleValuePending = _paddleValueProcessing = _paddleValueApplied = 0;
|
_paddleValuePending = _paddleValueProcessing = _paddleValueApplied = 0;
|
||||||
_paddleAdjustPending = _paddleAdjustProcessing = _paddleAdjustApplied = 0;
|
_paddleAdjustPending = _paddleAdjustProcessing = _paddleAdjustApplied = 0;
|
||||||
|
|
||||||
_softwareMicSampleGeneratorPending = _softwareMicSampleGeneratorProcessing = _softwareMicSampleGeneratorApplied = _nullSampleGenerator;
|
_softwareMicSampleGeneratorPending = _nullSampleGenerator;
|
||||||
|
_softwareMicSampleGeneratorProcessing = _nullSampleGenerator;
|
||||||
|
_softwareMicSampleGeneratorApplied = _nullSampleGenerator;
|
||||||
|
|
||||||
memset(_clientInputPending, 0, sizeof(_clientInputPending));
|
memset(_clientInputPending, 0, sizeof(_clientInputPending));
|
||||||
memset(_clientInputProcessing, 0, sizeof(_clientInputProcessing));
|
memset(_clientInputProcessing, 0, sizeof(_clientInputProcessing));
|
||||||
|
@ -257,6 +266,35 @@ void ClientInputHandler::SetSineWaveFrequency(double freq)
|
||||||
this->_sineWaveGenerator->setFrequency(freq);
|
this->_sineWaveGenerator->setFrequency(freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ClientInputHandler::GetAverageMicLevel()
|
||||||
|
{
|
||||||
|
return this->_avgMicLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::AddSampleToAverageMicLevel(uint8_t sampleValue)
|
||||||
|
{
|
||||||
|
this->_avgMicLevelTotal += (float)( (MIC_NULL_SAMPLE_VALUE > sampleValue) ? MIC_NULL_SAMPLE_VALUE - sampleValue : sampleValue - MIC_NULL_SAMPLE_VALUE );
|
||||||
|
this->_avgMicLevelsRead += 1.0f;
|
||||||
|
this->_avgMicLevel = this->_avgMicLevelTotal / this->_avgMicLevelsRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::ClearAverageMicLevel()
|
||||||
|
{
|
||||||
|
this->_avgMicLevelTotal = 0.0f;
|
||||||
|
this->_avgMicLevelsRead = 0.0f;
|
||||||
|
this->_avgMicLevel = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientInputHandler::IsMicrophoneIdle()
|
||||||
|
{
|
||||||
|
return (this->_avgMicLevel < MIC_NULL_LEVEL_THRESHOLD);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientInputHandler::IsMicrophoneClipping()
|
||||||
|
{
|
||||||
|
return (this->_avgMicLevel >= MIC_CLIP_LEVEL_THRESHOLD);
|
||||||
|
}
|
||||||
|
|
||||||
AudioGenerator* ClientInputHandler::GetClientSoftwareMicSampleGenerator()
|
AudioGenerator* ClientInputHandler::GetClientSoftwareMicSampleGenerator()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&this->_mutexInputsPending);
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
@ -287,6 +325,23 @@ void ClientInputHandler::SetClientSelectedAudioFileGenerator(AudioSampleBlockGen
|
||||||
pthread_mutex_unlock(&this->_mutexInputsPending);
|
pthread_mutex_unlock(&this->_mutexInputsPending);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::SetClientHardwareMicSampleGeneratorApplied(AudioGenerator *hwGenerator)
|
||||||
|
{
|
||||||
|
if (hwGenerator == NULL)
|
||||||
|
{
|
||||||
|
this->_hardwareMicSampleGenerator = this->_nullSampleGenerator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->_hardwareMicSampleGenerator = hwGenerator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioGenerator* ClientInputHandler::GetClientHardwareMicSampleGeneratorApplied()
|
||||||
|
{
|
||||||
|
return this->_hardwareMicSampleGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
bool ClientInputHandler::GetClientSoftwareMicState()
|
bool ClientInputHandler::GetClientSoftwareMicState()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&this->_mutexInputsPending);
|
pthread_mutex_lock(&this->_mutexInputsPending);
|
||||||
|
@ -611,3 +666,73 @@ void ClientInputHandler::ApplyInputs()
|
||||||
FCEUMOV_HandleRecording();
|
FCEUMOV_HandleRecording();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientInputHandler::IsHardwareMicAvailable()
|
||||||
|
{
|
||||||
|
// Do nothing. This is implementation-dependent.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::ResetHardwareMic()
|
||||||
|
{
|
||||||
|
this->ClearAverageMicLevel();
|
||||||
|
this->ReportAverageMicLevel();
|
||||||
|
|
||||||
|
this->_hardwareMicSampleGenerator->resetSamples();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ClientInputHandler::HandleMicSampleRead()
|
||||||
|
{
|
||||||
|
uint8_t theSample = MIC_NULL_SAMPLE_VALUE;
|
||||||
|
AudioGenerator *sampleGenerator = (this->GetClientSoftwareMicStateApplied()) ? this->GetClientSoftwareMicSampleGeneratorApplied() : this->_hardwareMicSampleGenerator;
|
||||||
|
|
||||||
|
theSample = sampleGenerator->generateSample();
|
||||||
|
|
||||||
|
this->AddSampleToAverageMicLevel(theSample);
|
||||||
|
return theSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::ReportAverageMicLevel()
|
||||||
|
{
|
||||||
|
// Do nothing. This is implementation-dependent.
|
||||||
|
// This method mainly exists for implementations to do some stuff during the
|
||||||
|
// emulation loop.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientInputHandler::GetHardwareMicMute()
|
||||||
|
{
|
||||||
|
return this->_isHardwareMicMuted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::SetHardwareMicMute(bool muteState)
|
||||||
|
{
|
||||||
|
this->_isHardwareMicMuted = muteState;
|
||||||
|
|
||||||
|
if (muteState)
|
||||||
|
{
|
||||||
|
this->_hardwareMicSampleGenerator->resetSamples();
|
||||||
|
this->ClearAverageMicLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientInputHandler::GetHardwareMicPause()
|
||||||
|
{
|
||||||
|
return this->_isHardwareMicPaused;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::SetHardwareMicPause(bool pauseState)
|
||||||
|
{
|
||||||
|
this->_isHardwareMicPaused = pauseState;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ClientInputHandler::GetHardwareMicNormalizedGain()
|
||||||
|
{
|
||||||
|
// Do nothing. This is implementation-dependent.
|
||||||
|
// The default value is 0.0f, which represents 0.0% of the hardware device's pickup sensitivity.
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientInputHandler::SetHardwareMicGainAsNormalized(float normalizedGain)
|
||||||
|
{
|
||||||
|
// Do nothing. This is implementation-dependent.
|
||||||
|
}
|
||||||
|
|
|
@ -330,6 +330,8 @@ protected:
|
||||||
SineWaveGenerator *_sineWaveGenerator;
|
SineWaveGenerator *_sineWaveGenerator;
|
||||||
AudioSampleBlockGenerator *_selectedAudioFileGenerator;
|
AudioSampleBlockGenerator *_selectedAudioFileGenerator;
|
||||||
|
|
||||||
|
AudioGenerator *_hardwareMicSampleGenerator;
|
||||||
|
|
||||||
ClientInput _clientInputPending[NDSInputID_InputCount];
|
ClientInput _clientInputPending[NDSInputID_InputCount];
|
||||||
ClientInput _clientInputProcessing[NDSInputID_InputCount];
|
ClientInput _clientInputProcessing[NDSInputID_InputCount];
|
||||||
ClientInput _clientInputApplied[NDSInputID_InputCount];
|
ClientInput _clientInputApplied[NDSInputID_InputCount];
|
||||||
|
@ -354,6 +356,12 @@ protected:
|
||||||
int16_t _paddleValueApplied;
|
int16_t _paddleValueApplied;
|
||||||
int16_t _paddleAdjustApplied;
|
int16_t _paddleAdjustApplied;
|
||||||
|
|
||||||
|
float _avgMicLevel;
|
||||||
|
float _avgMicLevelTotal;
|
||||||
|
float _avgMicLevelsRead;
|
||||||
|
bool _isHardwareMicMuted;
|
||||||
|
bool _isHardwareMicPaused;
|
||||||
|
|
||||||
pthread_mutex_t _mutexInputsPending;
|
pthread_mutex_t _mutexInputsPending;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -374,11 +382,21 @@ public:
|
||||||
double GetSineWaveFrequency();
|
double GetSineWaveFrequency();
|
||||||
void SetSineWaveFrequency(double freq);
|
void SetSineWaveFrequency(double freq);
|
||||||
|
|
||||||
|
float GetAverageMicLevel();
|
||||||
|
void AddSampleToAverageMicLevel(uint8_t sampleValue);
|
||||||
|
void ClearAverageMicLevel();
|
||||||
|
|
||||||
|
bool IsMicrophoneIdle();
|
||||||
|
bool IsMicrophoneClipping();
|
||||||
|
|
||||||
AudioGenerator* GetClientSoftwareMicSampleGenerator();
|
AudioGenerator* GetClientSoftwareMicSampleGenerator();
|
||||||
AudioGenerator* GetClientSoftwareMicSampleGeneratorApplied();
|
AudioGenerator* GetClientSoftwareMicSampleGeneratorApplied();
|
||||||
AudioSampleBlockGenerator* GetClientSelectedAudioFileGenerator();
|
AudioSampleBlockGenerator* GetClientSelectedAudioFileGenerator();
|
||||||
void SetClientSelectedAudioFileGenerator(AudioSampleBlockGenerator *selectedAudioFileGenerator);
|
void SetClientSelectedAudioFileGenerator(AudioSampleBlockGenerator *selectedAudioFileGenerator);
|
||||||
|
|
||||||
|
void SetClientHardwareMicSampleGeneratorApplied(AudioGenerator *hwGenerator);
|
||||||
|
AudioGenerator* GetClientHardwareMicSampleGeneratorApplied();
|
||||||
|
|
||||||
bool GetClientSoftwareMicState();
|
bool GetClientSoftwareMicState();
|
||||||
bool GetClientSoftwareMicStateApplied();
|
bool GetClientSoftwareMicStateApplied();
|
||||||
void SetClientSoftwareMicState(bool pressedState, MicrophoneMode micMode);
|
void SetClientSoftwareMicState(bool pressedState, MicrophoneMode micMode);
|
||||||
|
@ -395,6 +413,20 @@ public:
|
||||||
|
|
||||||
void ProcessInputs();
|
void ProcessInputs();
|
||||||
void ApplyInputs();
|
void ApplyInputs();
|
||||||
|
|
||||||
|
virtual bool IsHardwareMicAvailable();
|
||||||
|
virtual void ResetHardwareMic();
|
||||||
|
virtual uint8_t HandleMicSampleRead();
|
||||||
|
virtual void ReportAverageMicLevel();
|
||||||
|
|
||||||
|
virtual bool GetHardwareMicMute();
|
||||||
|
virtual void SetHardwareMicMute(bool muteState);
|
||||||
|
|
||||||
|
virtual bool GetHardwareMicPause();
|
||||||
|
virtual void SetHardwareMicPause(bool pauseState);
|
||||||
|
|
||||||
|
virtual float GetHardwareMicNormalizedGain();
|
||||||
|
virtual void SetHardwareMicGainAsNormalized(float normalizedGain);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CLIENT_INPUT_HANDLER_H_
|
#endif // _CLIENT_INPUT_HANDLER_H_
|
||||||
|
|
|
@ -33,6 +33,21 @@ static const uint8_t noiseSample[NUM_INTERNAL_NOISE_SAMPLES] =
|
||||||
0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01
|
0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01
|
||||||
};
|
};
|
||||||
|
|
||||||
|
size_t AudioGenerator::resetSamples()
|
||||||
|
{
|
||||||
|
// Do nothing. This is implementation-dependent.
|
||||||
|
//
|
||||||
|
// The return value represents the number of samples that were dropped.
|
||||||
|
// By default, return 0 to signify that no samples are dropped. In other
|
||||||
|
// words, all samples will continue to exist after the reset.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AudioGenerator::generateSample()
|
||||||
|
{
|
||||||
|
return MIC_NULL_SAMPLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t AudioGenerator::generateSampleBlock(size_t sampleCount, uint8_t *outBuffer)
|
size_t AudioGenerator::generateSampleBlock(size_t sampleCount, uint8_t *outBuffer)
|
||||||
{
|
{
|
||||||
if (outBuffer == NULL)
|
if (outBuffer == NULL)
|
||||||
|
@ -48,11 +63,6 @@ size_t AudioGenerator::generateSampleBlock(size_t sampleCount, uint8_t *outBuffe
|
||||||
return sampleCount;
|
return sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t AudioGenerator::generateSample()
|
|
||||||
{
|
|
||||||
return MIC_NULL_SAMPLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioSampleBlockGenerator::AudioSampleBlockGenerator(const uint8_t *audioBuffer, const size_t sampleCount)
|
AudioSampleBlockGenerator::AudioSampleBlockGenerator(const uint8_t *audioBuffer, const size_t sampleCount)
|
||||||
{
|
{
|
||||||
_buffer = (uint8_t *)malloc(sampleCount * sizeof(uint8_t));
|
_buffer = (uint8_t *)malloc(sampleCount * sizeof(uint8_t));
|
||||||
|
|
|
@ -28,8 +28,9 @@ public:
|
||||||
AudioGenerator() {};
|
AudioGenerator() {};
|
||||||
virtual ~AudioGenerator() {};
|
virtual ~AudioGenerator() {};
|
||||||
|
|
||||||
virtual size_t generateSampleBlock(size_t sampleCount, uint8_t *outBuffer);
|
virtual size_t resetSamples();
|
||||||
virtual uint8_t generateSample();
|
virtual uint8_t generateSample();
|
||||||
|
virtual size_t generateSampleBlock(size_t sampleCount, uint8_t *outBuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NullGenerator : public AudioGenerator {};
|
class NullGenerator : public AudioGenerator {};
|
||||||
|
|
|
@ -870,7 +870,6 @@ volatile bool execute = true;
|
||||||
[self setMasterExecute:YES];
|
[self setMasterExecute:YES];
|
||||||
[self restoreCoreState];
|
[self restoreCoreState];
|
||||||
[[self cdsController] reset];
|
[[self cdsController] reset];
|
||||||
[[self cdsController] updateMicLevel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) getTimedEmulatorStatistics:(NSTimer *)timer
|
- (void) getTimedEmulatorStatistics:(NSTimer *)timer
|
||||||
|
@ -1159,6 +1158,10 @@ static void* RunCoreThread(void *arg)
|
||||||
NDSError ndsError = NDS_GetLastError();
|
NDSError ndsError = NDS_GetLastError();
|
||||||
pthread_mutex_unlock(¶m->mutexThreadExecute);
|
pthread_mutex_unlock(¶m->mutexThreadExecute);
|
||||||
|
|
||||||
|
inputHandler->SetHardwareMicPause(true);
|
||||||
|
inputHandler->ClearAverageMicLevel();
|
||||||
|
inputHandler->ReportAverageMicLevel();
|
||||||
|
|
||||||
[cdsCore postNDSError:ndsError];
|
[cdsCore postNDSError:ndsError];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1167,9 +1170,8 @@ static void* RunCoreThread(void *arg)
|
||||||
// of whether the NDS actually reads the mic or not.
|
// of whether the NDS actually reads the mic or not.
|
||||||
if ((ndsFrameInfo.frameIndex & 0x07) == 0x07)
|
if ((ndsFrameInfo.frameIndex & 0x07) == 0x07)
|
||||||
{
|
{
|
||||||
CocoaDSController *cdsController = [cdsCore cdsController];
|
inputHandler->ReportAverageMicLevel();
|
||||||
[cdsController updateMicLevel];
|
inputHandler->ClearAverageMicLevel();
|
||||||
[cdsController clearMicLevelMeasure];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t framesToSkip = execControl->GetFramesToSkip();
|
const uint8_t framesToSkip = execControl->GetFramesToSkip();
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include <libkern/OSAtomic.h>
|
#include <libkern/OSAtomic.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ClientInputHandler.h"
|
||||||
|
|
||||||
@class CocoaDSController;
|
@class CocoaDSController;
|
||||||
class ClientInputHandler;
|
class ClientInputHandler;
|
||||||
class CoreAudioInput;
|
class CoreAudioInput;
|
||||||
|
@ -45,16 +47,7 @@ class AudioSampleBlockGenerator;
|
||||||
ClientInputHandler *inputHandler;
|
ClientInputHandler *inputHandler;
|
||||||
|
|
||||||
NSInteger stylusPressure;
|
NSInteger stylusPressure;
|
||||||
|
|
||||||
float micLevel;
|
|
||||||
float _micLevelTotal;
|
|
||||||
float _micLevelsRead;
|
|
||||||
|
|
||||||
BOOL hardwareMicMute;
|
|
||||||
size_t _availableMicSamples;
|
|
||||||
|
|
||||||
CoreAudioInput *CAInputDevice;
|
|
||||||
|
|
||||||
NSString *hardwareMicInfoString;
|
NSString *hardwareMicInfoString;
|
||||||
NSString *hardwareMicNameString;
|
NSString *hardwareMicNameString;
|
||||||
NSString *hardwareMicManufacturerString;
|
NSString *hardwareMicManufacturerString;
|
||||||
|
@ -70,13 +63,9 @@ class AudioSampleBlockGenerator;
|
||||||
@property (readonly) BOOL isHardwareMicIdle;
|
@property (readonly) BOOL isHardwareMicIdle;
|
||||||
@property (readonly) BOOL isHardwareMicInClip;
|
@property (readonly) BOOL isHardwareMicInClip;
|
||||||
@property (assign) float micLevel;
|
@property (assign) float micLevel;
|
||||||
@property (assign) BOOL hardwareMicEnabled;
|
|
||||||
@property (readonly) BOOL hardwareMicLocked;
|
|
||||||
@property (assign) float hardwareMicGain;
|
@property (assign) float hardwareMicGain;
|
||||||
@property (assign) BOOL hardwareMicMute;
|
@property (assign) BOOL hardwareMicMute;
|
||||||
@property (assign) BOOL hardwareMicPause;
|
@property (assign) BOOL hardwareMicPause;
|
||||||
@property (readonly) CoreAudioInput *CAInputDevice;
|
|
||||||
@property (readonly) AudioGenerator *softwareMicSampleGenerator;
|
|
||||||
@property (assign) AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
@property (assign) AudioSampleBlockGenerator *selectedAudioFileGenerator;
|
||||||
@property (retain) NSString *hardwareMicInfoString;
|
@property (retain) NSString *hardwareMicInfoString;
|
||||||
@property (retain) NSString *hardwareMicNameString;
|
@property (retain) NSString *hardwareMicNameString;
|
||||||
|
@ -91,10 +80,8 @@ class AudioSampleBlockGenerator;
|
||||||
- (void) setSineWaveGeneratorFrequency:(const double)freq;
|
- (void) setSineWaveGeneratorFrequency:(const double)freq;
|
||||||
- (void) clearAutohold;
|
- (void) clearAutohold;
|
||||||
- (void) reset;
|
- (void) reset;
|
||||||
|
- (void) startHardwareMicDevice;
|
||||||
|
|
||||||
- (void) clearMicLevelMeasure;
|
|
||||||
- (void) updateMicLevel;
|
|
||||||
- (uint8_t) handleMicSampleRead:(CoreAudioInput *)caInput softwareMic:(AudioGenerator *)sampleGenerator;
|
|
||||||
- (void) handleMicHardwareStateChanged:(CoreAudioInputDeviceInfo *)deviceInfo
|
- (void) handleMicHardwareStateChanged:(CoreAudioInputDeviceInfo *)deviceInfo
|
||||||
isEnabled:(BOOL)isHardwareEnabled
|
isEnabled:(BOOL)isHardwareEnabled
|
||||||
isLocked:(BOOL)isHardwareLocked;
|
isLocked:(BOOL)isHardwareLocked;
|
||||||
|
@ -102,6 +89,33 @@ class AudioSampleBlockGenerator;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
class MacInputHandler : public ClientInputHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CocoaDSController *_cdsController;
|
||||||
|
CoreAudioInput *_CAInputDevice;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacInputHandler();
|
||||||
|
~MacInputHandler();
|
||||||
|
|
||||||
|
CocoaDSController* GetCocoaController();
|
||||||
|
void SetCocoaController(CocoaDSController *theController);
|
||||||
|
|
||||||
|
void StartHardwareMicDevice();
|
||||||
|
|
||||||
|
virtual bool IsHardwareMicAvailable();
|
||||||
|
virtual void ReportAverageMicLevel();
|
||||||
|
|
||||||
|
virtual void SetHardwareMicMute(bool muteState);
|
||||||
|
|
||||||
|
virtual bool GetHardwareMicPause();
|
||||||
|
virtual void SetHardwareMicPause(bool pauseState);
|
||||||
|
|
||||||
|
virtual float GetHardwareMicNormalizedGain();
|
||||||
|
virtual void SetHardwareMicGainAsNormalized(float normalizedGain);
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
#include "../../slot2.h"
|
#include "../../slot2.h"
|
||||||
#undef BOOL
|
#undef BOOL
|
||||||
|
|
||||||
#include "ClientInputHandler.h"
|
|
||||||
|
|
||||||
|
|
||||||
@implementation CocoaDSController
|
@implementation CocoaDSController
|
||||||
|
|
||||||
|
@ -39,14 +37,10 @@
|
||||||
@dynamic isHardwareMicAvailable;
|
@dynamic isHardwareMicAvailable;
|
||||||
@dynamic isHardwareMicIdle;
|
@dynamic isHardwareMicIdle;
|
||||||
@dynamic isHardwareMicInClip;
|
@dynamic isHardwareMicInClip;
|
||||||
@synthesize micLevel;
|
@dynamic micLevel;
|
||||||
@dynamic hardwareMicEnabled;
|
|
||||||
@dynamic hardwareMicLocked;
|
|
||||||
@dynamic hardwareMicGain;
|
@dynamic hardwareMicGain;
|
||||||
@synthesize hardwareMicMute;
|
@dynamic hardwareMicMute;
|
||||||
@dynamic hardwareMicPause;
|
@dynamic hardwareMicPause;
|
||||||
@synthesize CAInputDevice;
|
|
||||||
@dynamic softwareMicSampleGenerator;
|
|
||||||
@dynamic selectedAudioFileGenerator;
|
@dynamic selectedAudioFileGenerator;
|
||||||
@synthesize hardwareMicInfoString;
|
@synthesize hardwareMicInfoString;
|
||||||
@synthesize hardwareMicNameString;
|
@synthesize hardwareMicNameString;
|
||||||
|
@ -62,32 +56,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate = nil;
|
delegate = nil;
|
||||||
inputHandler = new ClientInputHandler;
|
|
||||||
_availableMicSamples = 0;
|
|
||||||
|
|
||||||
micLevel = 0.0f;
|
|
||||||
_micLevelTotal = 0.0f;
|
|
||||||
_micLevelsRead = 0.0f;
|
|
||||||
|
|
||||||
CAInputDevice = new CoreAudioInput;
|
|
||||||
CAInputDevice->SetCallbackHardwareStateChanged(&CAHardwareStateChangedCallback, self, NULL);
|
|
||||||
CAInputDevice->SetCallbackHardwareGainChanged(&CAHardwareGainChangedCallback, self, NULL);
|
|
||||||
|
|
||||||
hardwareMicInfoString = @"No hardware input detected.";
|
hardwareMicInfoString = @"No hardware input detected.";
|
||||||
hardwareMicNameString = @"No hardware input detected.";
|
hardwareMicNameString = @"No hardware input detected.";
|
||||||
hardwareMicManufacturerString = @"No hardware input detected.";
|
hardwareMicManufacturerString = @"No hardware input detected.";
|
||||||
hardwareMicSampleRateString = @"No hardware input detected.";
|
hardwareMicSampleRateString = @"No hardware input detected.";
|
||||||
|
|
||||||
Mic_SetResetCallback(&CAResetCallback, self, NULL);
|
inputHandler = new MacInputHandler;
|
||||||
Mic_SetSampleReadCallback(&CASampleReadCallback, self, NULL);
|
((MacInputHandler *)inputHandler)->SetCocoaController(self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
delete CAInputDevice;
|
|
||||||
|
|
||||||
[self setDelegate:nil];
|
[self setDelegate:nil];
|
||||||
[self setHardwareMicInfoString:nil];
|
[self setHardwareMicInfoString:nil];
|
||||||
[self setHardwareMicNameString:nil];
|
[self setHardwareMicNameString:nil];
|
||||||
|
@ -104,62 +86,66 @@
|
||||||
|
|
||||||
- (BOOL) isHardwareMicAvailable
|
- (BOOL) isHardwareMicAvailable
|
||||||
{
|
{
|
||||||
return ( CAInputDevice->IsHardwareEnabled() &&
|
return (inputHandler->IsHardwareMicAvailable()) ? YES : NO;
|
||||||
!CAInputDevice->IsHardwareLocked() &&
|
|
||||||
!CAInputDevice->GetPauseState() ) ? YES : NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isHardwareMicIdle
|
- (BOOL) isHardwareMicIdle
|
||||||
{
|
{
|
||||||
return (micLevel < MIC_NULL_LEVEL_THRESHOLD);
|
return (inputHandler->IsMicrophoneIdle()) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isHardwareMicInClip
|
- (BOOL) isHardwareMicInClip
|
||||||
{
|
{
|
||||||
return (micLevel >= MIC_CLIP_LEVEL_THRESHOLD);
|
return (inputHandler->IsMicrophoneClipping()) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setHardwareMicEnabled:(BOOL)micEnabled
|
- (void) setMicLevel:(float)micLevelValue
|
||||||
{
|
{
|
||||||
if (micEnabled)
|
// This method doesn't set the mic level, since the mic level is always an internally
|
||||||
|
// calculated value. What this method actually does is trigger updates for any
|
||||||
|
// KVO-compliant controls that are associated with this property.
|
||||||
|
|
||||||
|
if ( (delegate != nil) && [delegate respondsToSelector:@selector(doMicLevelUpdateFromController:)] )
|
||||||
{
|
{
|
||||||
CAInputDevice->Start();
|
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
||||||
}
|
[[self delegate] doMicLevelUpdateFromController:self];
|
||||||
else
|
[tempPool release];
|
||||||
{
|
|
||||||
CAInputDevice->Stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) hardwareMicEnabled
|
- (float) micLevel
|
||||||
{
|
{
|
||||||
return (CAInputDevice->IsHardwareEnabled()) ? YES : NO;
|
return inputHandler->GetAverageMicLevel();
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL) hardwareMicLocked
|
|
||||||
{
|
|
||||||
return (CAInputDevice->IsHardwareLocked()) ? YES : NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setHardwareMicGain:(float)micGain
|
- (void) setHardwareMicGain:(float)micGain
|
||||||
{
|
{
|
||||||
CAInputDevice->SetGain(micGain);
|
inputHandler->SetHardwareMicGainAsNormalized(micGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (float) hardwareMicGain
|
- (float) hardwareMicGain
|
||||||
{
|
{
|
||||||
return CAInputDevice->GetGain();
|
return inputHandler->GetHardwareMicNormalizedGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHardwareMicMute:(BOOL)isMicMuted
|
||||||
|
{
|
||||||
|
inputHandler->SetHardwareMicMute((isMicMuted) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) hardwareMicMute
|
||||||
|
{
|
||||||
|
return (inputHandler->GetHardwareMicMute()) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setHardwareMicPause:(BOOL)isMicPaused
|
- (void) setHardwareMicPause:(BOOL)isMicPaused
|
||||||
{
|
{
|
||||||
bool pauseState = (isMicPaused || [self hardwareMicMute]) ? true : false;
|
inputHandler->SetHardwareMicPause((isMicPaused) ? true : false);
|
||||||
CAInputDevice->SetPauseState(pauseState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) hardwareMicPause
|
- (BOOL) hardwareMicPause
|
||||||
{
|
{
|
||||||
return (CAInputDevice->GetPauseState()) ? YES : NO;
|
return (inputHandler->GetHardwareMicPause()) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setSoftwareMicState:(BOOL)theState mode:(NSInteger)micMode
|
- (void) setSoftwareMicState:(BOOL)theState mode:(NSInteger)micMode
|
||||||
|
@ -172,11 +158,6 @@
|
||||||
return (inputHandler->GetClientSoftwareMicState()) ? YES : NO;
|
return (inputHandler->GetClientSoftwareMicState()) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioGenerator *) softwareMicSampleGenerator
|
|
||||||
{
|
|
||||||
return inputHandler->GetClientSoftwareMicSampleGenerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setSelectedAudioFileGenerator:(AudioSampleBlockGenerator *)audioGenerator
|
- (void) setSelectedAudioFileGenerator:(AudioSampleBlockGenerator *)audioGenerator
|
||||||
{
|
{
|
||||||
inputHandler->SetClientSelectedAudioFileGenerator(audioGenerator);
|
inputHandler->SetClientSelectedAudioFileGenerator(audioGenerator);
|
||||||
|
@ -246,63 +227,13 @@
|
||||||
- (void) reset
|
- (void) reset
|
||||||
{
|
{
|
||||||
[self setAutohold:NO];
|
[self setAutohold:NO];
|
||||||
[self setMicLevel:0.0f];
|
|
||||||
[self clearMicLevelMeasure];
|
|
||||||
|
|
||||||
_availableMicSamples = 0;
|
inputHandler->ResetHardwareMic();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) clearMicLevelMeasure
|
- (void) startHardwareMicDevice
|
||||||
{
|
{
|
||||||
_micLevelTotal = 0.0f;
|
((MacInputHandler *)inputHandler)->StartHardwareMicDevice();
|
||||||
_micLevelsRead = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) updateMicLevel
|
|
||||||
{
|
|
||||||
float avgMicLevel = (_micLevelsRead != 0) ? _micLevelTotal / _micLevelsRead : 0.0f;
|
|
||||||
|
|
||||||
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
|
||||||
[self setMicLevel:avgMicLevel];
|
|
||||||
|
|
||||||
if (delegate != nil && [delegate respondsToSelector:@selector(doMicLevelUpdateFromController:)])
|
|
||||||
{
|
|
||||||
[[self delegate] doMicLevelUpdateFromController:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
[tempPool release];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (uint8_t) handleMicSampleRead:(CoreAudioInput *)caInput softwareMic:(AudioGenerator *)sampleGenerator
|
|
||||||
{
|
|
||||||
uint8_t theSample = MIC_NULL_SAMPLE_VALUE;
|
|
||||||
|
|
||||||
if (!inputHandler->GetClientSoftwareMicStateApplied() && (caInput != NULL))
|
|
||||||
{
|
|
||||||
if (caInput->GetPauseState())
|
|
||||||
{
|
|
||||||
return theSample;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_availableMicSamples == 0)
|
|
||||||
{
|
|
||||||
_availableMicSamples = CAInputDevice->Pull();
|
|
||||||
}
|
|
||||||
|
|
||||||
caInput->_samplesConverted->read(&theSample, 1);
|
|
||||||
theSample >>= 1; // Samples from CoreAudio are 8-bit, so we need to convert the sample to 7-bit
|
|
||||||
_availableMicSamples--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
theSample = sampleGenerator->generateSample();
|
|
||||||
}
|
|
||||||
|
|
||||||
_micLevelTotal += (float)( (MIC_NULL_SAMPLE_VALUE > theSample) ? MIC_NULL_SAMPLE_VALUE - theSample : theSample - MIC_NULL_SAMPLE_VALUE );
|
|
||||||
_micLevelsRead += 1.0f;
|
|
||||||
return theSample;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) handleMicHardwareStateChanged:(CoreAudioInputDeviceInfo *)deviceInfo
|
- (void) handleMicHardwareStateChanged:(CoreAudioInputDeviceInfo *)deviceInfo
|
||||||
|
@ -329,10 +260,10 @@
|
||||||
[self setHardwareMicSampleRateString:[NSString stringWithFormat:@"%1.1f Hz", (double)deviceInfo->sampleRate]];
|
[self setHardwareMicSampleRateString:[NSString stringWithFormat:@"%1.1f Hz", (double)deviceInfo->sampleRate]];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self clearMicLevelMeasure];
|
inputHandler->ClearAverageMicLevel();
|
||||||
[self setMicLevel:0.0f];
|
inputHandler->ReportAverageMicLevel();
|
||||||
|
|
||||||
if (delegate != nil && [delegate respondsToSelector:@selector(doMicHardwareStateChangedFromController:isEnabled:isLocked:)])
|
if ( (delegate != nil) && [delegate respondsToSelector:@selector(doMicHardwareStateChangedFromController:isEnabled:isLocked:)] )
|
||||||
{
|
{
|
||||||
[[self delegate] doMicHardwareStateChangedFromController:self
|
[[self delegate] doMicHardwareStateChangedFromController:self
|
||||||
isEnabled:isHardwareEnabled
|
isEnabled:isHardwareEnabled
|
||||||
|
@ -344,7 +275,7 @@
|
||||||
|
|
||||||
- (void) handleMicHardwareGainChanged:(float)gainValue
|
- (void) handleMicHardwareGainChanged:(float)gainValue
|
||||||
{
|
{
|
||||||
if (delegate != nil && [delegate respondsToSelector:@selector(doMicHardwareGainChangedFromController:gain:)])
|
if ( (delegate != nil) && [delegate respondsToSelector:@selector(doMicHardwareGainChangedFromController:gain:)] )
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
||||||
[[self delegate] doMicHardwareGainChangedFromController:self gain:gainValue];
|
[[self delegate] doMicHardwareGainChangedFromController:self gain:gainValue];
|
||||||
|
@ -354,16 +285,105 @@
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
MacInputHandler::MacInputHandler()
|
||||||
|
{
|
||||||
|
_cdsController = nil;
|
||||||
|
_CAInputDevice = new CoreAudioInput;
|
||||||
|
_hardwareMicSampleGenerator = _CAInputDevice;
|
||||||
|
_isHardwareMicMuted = false;
|
||||||
|
|
||||||
|
_CAInputDevice->SetCallbackHardwareStateChanged(&CAHardwareStateChangedCallback, _cdsController, NULL);
|
||||||
|
_CAInputDevice->SetCallbackHardwareGainChanged(&CAHardwareGainChangedCallback, _cdsController, NULL);
|
||||||
|
|
||||||
|
Mic_SetResetCallback(&CAResetCallback, _CAInputDevice, NULL);
|
||||||
|
Mic_SetSampleReadCallback(&CASampleReadCallback, this, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
MacInputHandler::~MacInputHandler()
|
||||||
|
{
|
||||||
|
delete this->_CAInputDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
CocoaDSController* MacInputHandler::GetCocoaController()
|
||||||
|
{
|
||||||
|
return this->_cdsController;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacInputHandler::SetCocoaController(CocoaDSController *theController)
|
||||||
|
{
|
||||||
|
this->_cdsController = theController;
|
||||||
|
this->_CAInputDevice->SetCallbackHardwareStateChanged(&CAHardwareStateChangedCallback, theController, NULL);
|
||||||
|
this->_CAInputDevice->SetCallbackHardwareGainChanged(&CAHardwareGainChangedCallback, theController, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacInputHandler::StartHardwareMicDevice()
|
||||||
|
{
|
||||||
|
this->_CAInputDevice->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacInputHandler::IsHardwareMicAvailable()
|
||||||
|
{
|
||||||
|
return ( this->_CAInputDevice->IsHardwareEnabled() && !this->_CAInputDevice->IsHardwareLocked() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacInputHandler::ReportAverageMicLevel()
|
||||||
|
{
|
||||||
|
[this->_cdsController setMicLevel:this->GetAverageMicLevel()];
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacInputHandler::SetHardwareMicMute(bool muteState)
|
||||||
|
{
|
||||||
|
const bool needSetMuteState = (this->_isHardwareMicMuted != muteState);
|
||||||
|
|
||||||
|
if (needSetMuteState)
|
||||||
|
{
|
||||||
|
if (muteState)
|
||||||
|
{
|
||||||
|
this->_hardwareMicSampleGenerator->resetSamples();
|
||||||
|
this->ClearAverageMicLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_isHardwareMicMuted = muteState;
|
||||||
|
this->_CAInputDevice->SetPauseState(this->_isHardwareMicPaused || muteState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacInputHandler::GetHardwareMicPause()
|
||||||
|
{
|
||||||
|
return this->_CAInputDevice->GetPauseState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacInputHandler::SetHardwareMicPause(bool pauseState)
|
||||||
|
{
|
||||||
|
const bool needSetPauseState = (this->_isHardwareMicPaused != pauseState);
|
||||||
|
|
||||||
|
if (needSetPauseState)
|
||||||
|
{
|
||||||
|
this->_isHardwareMicPaused = pauseState;
|
||||||
|
this->_CAInputDevice->SetPauseState(pauseState || this->_isHardwareMicMuted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float MacInputHandler::GetHardwareMicNormalizedGain()
|
||||||
|
{
|
||||||
|
return this->_CAInputDevice->GetNormalizedGain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacInputHandler::SetHardwareMicGainAsNormalized(float normalizedGain)
|
||||||
|
{
|
||||||
|
this->_CAInputDevice->SetGainAsNormalized(normalizedGain);
|
||||||
|
}
|
||||||
|
|
||||||
void CAResetCallback(void *inParam1, void *inParam2)
|
void CAResetCallback(void *inParam1, void *inParam2)
|
||||||
{
|
{
|
||||||
CocoaDSController *cdsController = (CocoaDSController *)inParam1;
|
CoreAudioInput *caInputDevice = (CoreAudioInput *)inParam1;
|
||||||
[cdsController CAInputDevice]->Start();
|
caInputDevice->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t CASampleReadCallback(void *inParam1, void *inParam2)
|
uint8_t CASampleReadCallback(void *inParam1, void *inParam2)
|
||||||
{
|
{
|
||||||
CocoaDSController *cdsController = (CocoaDSController *)inParam1;
|
ClientInputHandler *inputHandler = (ClientInputHandler *)inParam1;
|
||||||
return [cdsController handleMicSampleRead:[cdsController CAInputDevice] softwareMic:[cdsController softwareMicSampleGenerator]];
|
return inputHandler->HandleMicSampleRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAHardwareStateChangedCallback(CoreAudioInputDeviceInfo *deviceInfo,
|
void CAHardwareStateChangedCallback(CoreAudioInputDeviceInfo *deviceInfo,
|
||||||
|
|
|
@ -47,7 +47,7 @@ CoreAudioInput::CoreAudioInput()
|
||||||
_hwDeviceInfo.deviceUID = CFSTR("");
|
_hwDeviceInfo.deviceUID = CFSTR("");
|
||||||
_hwDeviceInfo.modelUID = CFSTR("");
|
_hwDeviceInfo.modelUID = CFSTR("");
|
||||||
_hwDeviceInfo.sampleRate = 0.0;
|
_hwDeviceInfo.sampleRate = 0.0;
|
||||||
_isPaused = false;
|
_isPaused = true;
|
||||||
_isHardwareEnabled = false;
|
_isHardwareEnabled = false;
|
||||||
_isHardwareLocked = true;
|
_isHardwareLocked = true;
|
||||||
_captureFrames = 0;
|
_captureFrames = 0;
|
||||||
|
@ -602,12 +602,12 @@ void CoreAudioInput::SetPauseState(bool pauseState)
|
||||||
this->_isPaused = (this->IsHardwareLocked()) ? true : pauseState;
|
this->_isPaused = (this->IsHardwareLocked()) ? true : pauseState;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CoreAudioInput::GetGain() const
|
float CoreAudioInput::GetNormalizedGain() const
|
||||||
{
|
{
|
||||||
return this->_inputGainNormalized;
|
return this->_inputGainNormalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreAudioInput::SetGain(float normalizedGain)
|
void CoreAudioInput::SetGainAsNormalized(float normalizedGain)
|
||||||
{
|
{
|
||||||
Float32 gainValue = normalizedGain;
|
Float32 gainValue = normalizedGain;
|
||||||
UInt32 gainPropSize = sizeof(gainValue);
|
UInt32 gainPropSize = sizeof(gainValue);
|
||||||
|
@ -698,6 +698,36 @@ void CoreAudioInput::UpdateHardwareLock()
|
||||||
this->_hwStateChangedCallbackParam2);
|
this->_hwStateChangedCallbackParam2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t CoreAudioInput::resetSamples()
|
||||||
|
{
|
||||||
|
size_t samplesToDrop = this->_samplesConverted->getUsedElements();
|
||||||
|
this->_samplesConverted->clear();
|
||||||
|
|
||||||
|
return samplesToDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CoreAudioInput::generateSample()
|
||||||
|
{
|
||||||
|
uint8_t theSample = MIC_NULL_SAMPLE_VALUE;
|
||||||
|
|
||||||
|
if (this->_isPaused)
|
||||||
|
{
|
||||||
|
return theSample;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->_samplesConverted->getUsedElements() == 0)
|
||||||
|
{
|
||||||
|
this->Pull();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_samplesConverted->read(&theSample, 1);
|
||||||
|
theSample >>= 1; // Samples from CoreAudio are 8-bit, so we need to convert the sample to 7-bit
|
||||||
|
}
|
||||||
|
|
||||||
|
return theSample;
|
||||||
|
}
|
||||||
|
|
||||||
void CoreAudioInput::SetCallbackHardwareStateChanged(CoreAudioInputHardwareStateChangedCallback callbackFunc, void *inParam1, void *inParam2)
|
void CoreAudioInput::SetCallbackHardwareStateChanged(CoreAudioInputHardwareStateChangedCallback callbackFunc, void *inParam1, void *inParam2)
|
||||||
{
|
{
|
||||||
this->_hwStateChangedCallbackFunc = callbackFunc;
|
this->_hwStateChangedCallbackFunc = callbackFunc;
|
||||||
|
|
|
@ -22,8 +22,9 @@
|
||||||
#include <AudioUnit/AudioUnit.h>
|
#include <AudioUnit/AudioUnit.h>
|
||||||
#include <AudioToolbox/AudioToolbox.h>
|
#include <AudioToolbox/AudioToolbox.h>
|
||||||
#include <libkern/OSAtomic.h>
|
#include <libkern/OSAtomic.h>
|
||||||
#include "ringbuffer.h"
|
|
||||||
|
|
||||||
|
#include "ringbuffer.h"
|
||||||
|
#include "audiosamplegenerator.h"
|
||||||
|
|
||||||
struct CoreAudioInputDeviceInfo
|
struct CoreAudioInputDeviceInfo
|
||||||
{
|
{
|
||||||
|
@ -44,7 +45,7 @@ typedef void (*CoreAudioInputHardwareStateChangedCallback)(CoreAudioInputDeviceI
|
||||||
|
|
||||||
typedef void (*CoreAudioInputHardwareGainChangedCallback)(float normalizedGain, void *inParam1, void *inParam2);
|
typedef void (*CoreAudioInputHardwareGainChangedCallback)(float normalizedGain, void *inParam1, void *inParam2);
|
||||||
|
|
||||||
class CoreAudioInput
|
class CoreAudioInput : public AudioGenerator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
OSSpinLock *_spinlockAUHAL;
|
OSSpinLock *_spinlockAUHAL;
|
||||||
|
@ -65,6 +66,8 @@ private:
|
||||||
AudioBufferList *_convertBufferList;
|
AudioBufferList *_convertBufferList;
|
||||||
UInt32 _captureFrames;
|
UInt32 _captureFrames;
|
||||||
|
|
||||||
|
RingBuffer *_samplesConverted;
|
||||||
|
|
||||||
float _inputGainNormalized;
|
float _inputGainNormalized;
|
||||||
AudioUnitElement _inputElement;
|
AudioUnitElement _inputElement;
|
||||||
|
|
||||||
|
@ -80,10 +83,9 @@ public:
|
||||||
AudioTimeStamp _timeStamp;
|
AudioTimeStamp _timeStamp;
|
||||||
AudioBufferList *_captureBufferList;
|
AudioBufferList *_captureBufferList;
|
||||||
RingBuffer *_samplesCaptured;
|
RingBuffer *_samplesCaptured;
|
||||||
RingBuffer *_samplesConverted;
|
|
||||||
|
|
||||||
CoreAudioInput();
|
CoreAudioInput();
|
||||||
~CoreAudioInput();
|
virtual ~CoreAudioInput();
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -93,13 +95,16 @@ public:
|
||||||
bool IsHardwareLocked() const;
|
bool IsHardwareLocked() const;
|
||||||
bool GetPauseState() const;
|
bool GetPauseState() const;
|
||||||
void SetPauseState(bool pauseState);
|
void SetPauseState(bool pauseState);
|
||||||
float GetGain() const;
|
float GetNormalizedGain() const;
|
||||||
void SetGain(float normalizedGain);
|
void SetGainAsNormalized(float normalizedGain);
|
||||||
|
|
||||||
void UpdateHardwareGain(float normalizedGain);
|
void UpdateHardwareGain(float normalizedGain);
|
||||||
void UpdateHardwareLock();
|
void UpdateHardwareLock();
|
||||||
void SetCallbackHardwareStateChanged(CoreAudioInputHardwareStateChangedCallback callbackFunc, void *inParam1, void *inParam2);
|
void SetCallbackHardwareStateChanged(CoreAudioInputHardwareStateChangedCallback callbackFunc, void *inParam1, void *inParam2);
|
||||||
void SetCallbackHardwareGainChanged(CoreAudioInputHardwareGainChangedCallback callbackFunc, void *inParam1, void *inParam2);
|
void SetCallbackHardwareGainChanged(CoreAudioInputHardwareGainChangedCallback callbackFunc, void *inParam1, void *inParam2);
|
||||||
|
|
||||||
|
virtual size_t resetSamples();
|
||||||
|
virtual uint8_t generateSample();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CoreAudioOutput
|
class CoreAudioOutput
|
||||||
|
|
|
@ -810,7 +810,6 @@
|
||||||
const BOOL muteState = [CocoaDSUtil getIBActionSenderButtonStateBool:sender];
|
const BOOL muteState = [CocoaDSUtil getIBActionSenderButtonStateBool:sender];
|
||||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
||||||
[[cdsCore cdsController] setHardwareMicMute:muteState];
|
[[cdsCore cdsController] setHardwareMicMute:muteState];
|
||||||
[[cdsCore cdsController] setHardwareMicPause:([cdsCore coreState] != ExecutionBehavior_Run)];
|
|
||||||
[self updateMicStatusIcon];
|
[self updateMicStatusIcon];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,7 +1910,6 @@
|
||||||
|
|
||||||
[cdsCore setSlot1StatusText:NSSTRING_STATUS_EMULATION_NOT_RUNNING];
|
[cdsCore setSlot1StatusText:NSSTRING_STATUS_EMULATION_NOT_RUNNING];
|
||||||
[[cdsCore cdsController] reset];
|
[[cdsCore cdsController] reset];
|
||||||
[[cdsCore cdsController] updateMicLevel];
|
|
||||||
|
|
||||||
result = YES;
|
result = YES;
|
||||||
|
|
||||||
|
@ -2016,7 +2014,11 @@
|
||||||
{
|
{
|
||||||
if ([cdsController isHardwareMicAvailable])
|
if ([cdsController isHardwareMicAvailable])
|
||||||
{
|
{
|
||||||
if ([cdsController isHardwareMicInClip])
|
if ([cdsController hardwareMicPause])
|
||||||
|
{
|
||||||
|
micIcon = iconMicDisabled;
|
||||||
|
}
|
||||||
|
else if ([cdsController isHardwareMicInClip])
|
||||||
{
|
{
|
||||||
micIcon = iconMicInClip;
|
micIcon = iconMicInClip;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
|
|
||||||
// Init the DS controller.
|
// Init the DS controller.
|
||||||
[[newCore cdsController] setDelegate:emuControl];
|
[[newCore cdsController] setDelegate:emuControl];
|
||||||
[[newCore cdsController] setHardwareMicEnabled:YES];
|
[[newCore cdsController] startHardwareMicDevice];
|
||||||
|
|
||||||
// Init the DS speakers.
|
// Init the DS speakers.
|
||||||
CocoaDSSpeaker *newSpeaker = [[[CocoaDSSpeaker alloc] init] autorelease];
|
CocoaDSSpeaker *newSpeaker = [[[CocoaDSSpeaker alloc] init] autorelease];
|
||||||
|
@ -207,7 +207,6 @@
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
|
|
||||||
EmuControllerDelegate *emuControl = (EmuControllerDelegate *)[emuControlController content];
|
EmuControllerDelegate *emuControl = (EmuControllerDelegate *)[emuControlController content];
|
||||||
|
|
||||||
// Determine if the app was run for the first time.
|
// Determine if the app was run for the first time.
|
||||||
|
@ -237,11 +236,10 @@
|
||||||
[[inputPrefsView inputPrefOutlineView] expandItem:nil expandChildren:YES];
|
[[inputPrefsView inputPrefOutlineView] expandItem:nil expandChildren:YES];
|
||||||
[[inputPrefsView inputProfileMenu] selectItemAtIndex:0];
|
[[inputPrefsView inputProfileMenu] selectItemAtIndex:0];
|
||||||
|
|
||||||
// Make sure that the mic is paused to start with.
|
// Initialize the microphone status icon.
|
||||||
[[cdsCore cdsController] setHardwareMicPause:YES];
|
|
||||||
[emuControl updateMicStatusIcon];
|
[emuControl updateMicStatusIcon];
|
||||||
|
|
||||||
//Bring the application to the front
|
// Bring the application to the front
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
[self restoreDisplayWindowStates];
|
[self restoreDisplayWindowStates];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue