|
1 | 1 | /* |
2 | | - Copyright (C) 2012-2022 DeSmuME team |
| 2 | + Copyright (C) 2012-2025 DeSmuME team |
3 | 3 |
|
4 | 4 | This file is free software: you can redistribute it and/or modify |
5 | 5 | it under the terms of the GNU General Public License as published by |
|
16 | 16 | */ |
17 | 17 |
|
18 | 18 | #include "coreaudiosound.h" |
| 19 | +#include "MacCoreAudioOutputEngine.h" |
19 | 20 |
|
20 | 21 | #include <CoreAudio/CoreAudio.h> |
21 | 22 | #include "ClientInputHandler.h" |
@@ -903,206 +904,6 @@ void CoreAudioInputDefaultHardwareGainChangedCallback(float normalizedGain, void |
903 | 904 |
|
904 | 905 | #pragma mark - |
905 | 906 |
|
906 | | -CoreAudioOutput::CoreAudioOutput(size_t bufferSamples, size_t sampleSize) |
907 | | -{ |
908 | | - OSStatus error = noErr; |
909 | | - |
910 | | - _unfairlockAU = apple_unfairlock_create(); |
911 | | - |
912 | | - _buffer = new RingBuffer(bufferSamples, sampleSize); |
913 | | - _volume = 1.0f; |
914 | | - |
915 | | - // Create a new audio unit |
916 | | -#if !defined(FORCE_AUDIOCOMPONENT_10_5) && defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) |
917 | | - if (IsOSXVersionSupported(10, 6, 0)) |
918 | | - { |
919 | | - AudioComponentDescription audioDesc; |
920 | | - audioDesc.componentType = kAudioUnitType_Output; |
921 | | - audioDesc.componentSubType = kAudioUnitSubType_DefaultOutput; |
922 | | - audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple; |
923 | | - audioDesc.componentFlags = 0; |
924 | | - audioDesc.componentFlagsMask = 0; |
925 | | - |
926 | | - CreateAudioUnitInstance(&_au, &audioDesc); |
927 | | - } |
928 | | - else |
929 | | -#endif |
930 | | - { |
931 | | - ComponentDescription audioDesc; |
932 | | - audioDesc.componentType = kAudioUnitType_Output; |
933 | | - audioDesc.componentSubType = kAudioUnitSubType_DefaultOutput; |
934 | | - audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple; |
935 | | - audioDesc.componentFlags = 0; |
936 | | - audioDesc.componentFlagsMask = 0; |
937 | | - |
938 | | - CreateAudioUnitInstance(&_au, &audioDesc); |
939 | | - } |
940 | | - |
941 | | - // Set the render callback |
942 | | - AURenderCallbackStruct callback; |
943 | | - callback.inputProc = &CoreAudioOutputRenderCallback; |
944 | | - callback.inputProcRefCon = _buffer; |
945 | | - |
946 | | - error = AudioUnitSetProperty(_au, |
947 | | - kAudioUnitProperty_SetRenderCallback, |
948 | | - kAudioUnitScope_Input, |
949 | | - 0, |
950 | | - &callback, |
951 | | - sizeof(callback) ); |
952 | | - |
953 | | - if(error != noErr) |
954 | | - { |
955 | | - return; |
956 | | - } |
957 | | - |
958 | | - // Set up the audio unit for audio streaming |
959 | | - AudioStreamBasicDescription outputFormat; |
960 | | - outputFormat.mSampleRate = SPU_SAMPLE_RATE; |
961 | | - outputFormat.mFormatID = kAudioFormatLinearPCM; |
962 | | - outputFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked; |
963 | | - outputFormat.mBytesPerPacket = SPU_SAMPLE_SIZE; |
964 | | - outputFormat.mFramesPerPacket = 1; |
965 | | - outputFormat.mBytesPerFrame = SPU_SAMPLE_SIZE; |
966 | | - outputFormat.mChannelsPerFrame = SPU_NUMBER_CHANNELS; |
967 | | - outputFormat.mBitsPerChannel = SPU_SAMPLE_RESOLUTION; |
968 | | - |
969 | | - error = AudioUnitSetProperty(_au, |
970 | | - kAudioUnitProperty_StreamFormat, |
971 | | - kAudioUnitScope_Input, |
972 | | - 0, |
973 | | - &outputFormat, |
974 | | - sizeof(outputFormat) ); |
975 | | - |
976 | | - if(error != noErr) |
977 | | - { |
978 | | - return; |
979 | | - } |
980 | | - |
981 | | - // Initialize our new audio unit |
982 | | - error = AudioUnitInitialize(_au); |
983 | | - if(error != noErr) |
984 | | - { |
985 | | - return; |
986 | | - } |
987 | | -} |
988 | | - |
989 | | -CoreAudioOutput::~CoreAudioOutput() |
990 | | -{ |
991 | | - apple_unfairlock_lock(this->_unfairlockAU); |
992 | | - DestroyAudioUnitInstance(&this->_au); |
993 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
994 | | - |
995 | | - delete this->_buffer; |
996 | | - this->_buffer = NULL; |
997 | | - |
998 | | - apple_unfairlock_destroy(this->_unfairlockAU); |
999 | | -} |
1000 | | - |
1001 | | -void CoreAudioOutput::start() |
1002 | | -{ |
1003 | | - this->clearBuffer(); |
1004 | | - |
1005 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1006 | | - AudioUnitReset(this->_au, kAudioUnitScope_Global, 0); |
1007 | | - AudioOutputUnitStart(this->_au); |
1008 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1009 | | -} |
1010 | | - |
1011 | | -void CoreAudioOutput::pause() |
1012 | | -{ |
1013 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1014 | | - AudioOutputUnitStop(this->_au); |
1015 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1016 | | -} |
1017 | | - |
1018 | | -void CoreAudioOutput::unpause() |
1019 | | -{ |
1020 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1021 | | - AudioOutputUnitStart(this->_au); |
1022 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1023 | | -} |
1024 | | - |
1025 | | -void CoreAudioOutput::stop() |
1026 | | -{ |
1027 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1028 | | - AudioOutputUnitStop(this->_au); |
1029 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1030 | | - |
1031 | | - this->clearBuffer(); |
1032 | | -} |
1033 | | - |
1034 | | -void CoreAudioOutput::writeToBuffer(const void *buffer, size_t numberSampleFrames) |
1035 | | -{ |
1036 | | - size_t availableSampleFrames = this->_buffer->getAvailableElements(); |
1037 | | - if (availableSampleFrames < numberSampleFrames) |
1038 | | - { |
1039 | | - this->_buffer->drop(numberSampleFrames - availableSampleFrames); |
1040 | | - } |
1041 | | - |
1042 | | - this->_buffer->write(buffer, numberSampleFrames); |
1043 | | -} |
1044 | | - |
1045 | | -void CoreAudioOutput::clearBuffer() |
1046 | | -{ |
1047 | | - this->_buffer->clear(); |
1048 | | -} |
1049 | | - |
1050 | | -void CoreAudioOutput::mute() |
1051 | | -{ |
1052 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1053 | | - AudioUnitSetParameter(this->_au, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, 0.0f, 0); |
1054 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1055 | | -} |
1056 | | - |
1057 | | -void CoreAudioOutput::unmute() |
1058 | | -{ |
1059 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1060 | | - AudioUnitSetParameter(this->_au, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, this->_volume, 0); |
1061 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1062 | | -} |
1063 | | - |
1064 | | -size_t CoreAudioOutput::getAvailableSamples() const |
1065 | | -{ |
1066 | | - return this->_buffer->getAvailableElements(); |
1067 | | -} |
1068 | | - |
1069 | | -float CoreAudioOutput::getVolume() const |
1070 | | -{ |
1071 | | - return this->_volume; |
1072 | | -} |
1073 | | - |
1074 | | -void CoreAudioOutput::setVolume(float vol) |
1075 | | -{ |
1076 | | - this->_volume = vol; |
1077 | | - |
1078 | | - apple_unfairlock_lock(this->_unfairlockAU); |
1079 | | - AudioUnitSetParameter(this->_au, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0); |
1080 | | - apple_unfairlock_unlock(this->_unfairlockAU); |
1081 | | -} |
1082 | | - |
1083 | | -OSStatus CoreAudioOutputRenderCallback(void *inRefCon, |
1084 | | - AudioUnitRenderActionFlags *ioActionFlags, |
1085 | | - const AudioTimeStamp *inTimeStamp, |
1086 | | - UInt32 inBusNumber, |
1087 | | - UInt32 inNumberFrames, |
1088 | | - AudioBufferList *ioData) |
1089 | | -{ |
1090 | | - RingBuffer *__restrict__ audioBuffer = (RingBuffer *)inRefCon; |
1091 | | - UInt8 *__restrict__ playbackBuffer = (UInt8 *)ioData->mBuffers[0].mData; |
1092 | | - const size_t framesRead = audioBuffer->read(playbackBuffer, inNumberFrames); |
1093 | | - |
1094 | | - // Pad any remaining samples. |
1095 | | - if (framesRead < inNumberFrames) |
1096 | | - { |
1097 | | - const size_t frameSize = audioBuffer->getElementSize(); |
1098 | | - memset(playbackBuffer + (framesRead * frameSize), 0, (inNumberFrames - framesRead) * frameSize); |
1099 | | - } |
1100 | | - |
1101 | | - return noErr; |
1102 | | -} |
1103 | | - |
1104 | | -#pragma mark - |
1105 | | - |
1106 | 907 | bool CreateAudioUnitInstance(AudioUnit *au, ComponentDescription *auDescription) |
1107 | 908 | { |
1108 | 909 | bool result = false; |
|
0 commit comments