From bd571202e1080f84b341cfc3944b7cf8410e9bce Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 10 Apr 2013 21:59:55 +0000 Subject: [PATCH] Cocoa Port: - New feature: Audio files may now be used as audio generators for microphone input. Any Core Audio supported audio format may be used. - New feature: A sine wave tone audio generator is now available as a microphone input. - Fix bug where retrieving input device info from a CommandAttributes struct would retrieve garbage values if an object value was nil. - Fix bug where editing input settings would immediately change the input device info state, instead of waiting for user confirmation as intended. - Decouple the audio sample generation code from the microphone handling code. - Do some code cleanup. --- .../project.pbxproj | 46 +- .../project.pbxproj | 42 +- desmume/src/cocoa/DefaultKeyMappings.plist | 6 +- desmume/src/cocoa/audiosamplegenerator.cpp | 161 ++++ desmume/src/cocoa/audiosamplegenerator.h | 118 +++ desmume/src/cocoa/cocoa_globals.h | 11 +- desmume/src/cocoa/cocoa_input.h | 13 +- desmume/src/cocoa/cocoa_input.mm | 104 ++- desmume/src/cocoa/cocoa_mic.h | 63 -- desmume/src/cocoa/cocoa_mic.mm | 258 ------ desmume/src/cocoa/coreaudiosound.cpp | 24 +- desmume/src/cocoa/coreaudiosound.h | 6 +- desmume/src/cocoa/mic_ext.cpp | 102 +++ desmume/src/cocoa/mic_ext.h | 47 ++ desmume/src/cocoa/openemu/NDSGameCore.h | 14 +- desmume/src/cocoa/openemu/NDSGameCore.mm | 111 +-- desmume/src/cocoa/ringbuffer.cpp | 224 +++-- desmume/src/cocoa/ringbuffer.h | 15 +- desmume/src/cocoa/sndOSX.cpp | 2 +- .../English.lproj/MainMenu.strings | Bin 267714 -> 266758 bytes .../translations/English.lproj/MainMenu.xib | 786 ++++++++---------- .../userinterface/EmuControllerDelegate.h | 5 +- .../userinterface/EmuControllerDelegate.mm | 21 +- .../src/cocoa/userinterface/InputManager.h | 20 +- .../src/cocoa/userinterface/InputManager.mm | 289 +++++-- .../src/cocoa/userinterface/appDelegate.mm | 4 +- .../src/cocoa/userinterface/inputPrefsView.h | 5 + .../src/cocoa/userinterface/inputPrefsView.mm | 112 ++- .../preferencesWindowDelegate.mm | 1 - 29 files changed, 1509 insertions(+), 1101 deletions(-) create mode 100644 desmume/src/cocoa/audiosamplegenerator.cpp create mode 100644 desmume/src/cocoa/audiosamplegenerator.h delete mode 100644 desmume/src/cocoa/cocoa_mic.h delete mode 100644 desmume/src/cocoa/cocoa_mic.mm create mode 100644 desmume/src/cocoa/mic_ext.cpp create mode 100644 desmume/src/cocoa/mic_ext.h diff --git a/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj index c3ac93eee..923dc2a7c 100644 --- a/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj @@ -56,6 +56,14 @@ AB213D46170CB141006DDB0F /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB213D44170CB141006DDB0F /* InputProfileController.mm */; }; AB213D47170CB141006DDB0F /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB213D44170CB141006DDB0F /* InputProfileController.mm */; }; AB213D48170CB141006DDB0F /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB213D44170CB141006DDB0F /* InputProfileController.mm */; }; + AB213E991710D074006DDB0F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB213E981710D074006DDB0F /* AudioToolbox.framework */; }; + AB213EC41710D0A0006DDB0F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB213E981710D074006DDB0F /* AudioToolbox.framework */; }; + AB213EC51710D0A1006DDB0F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB213E981710D074006DDB0F /* AudioToolbox.framework */; }; + AB213EC61710D0A1006DDB0F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB213E981710D074006DDB0F /* AudioToolbox.framework */; }; + AB2145231714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */; }; + AB2145241714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */; }; + AB2145251714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */; }; + AB2145261714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */; }; AB2F3B7D15CF9C6000858373 /* KeyNames.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB02475B13886BF300E9F9AB /* KeyNames.plist */; }; AB2F3B7E15CF9C6000858373 /* DefaultKeyMappings.plist in Resources */ = {isa = PBXBuildFile; fileRef = ABC719E1138CB25E002827A9 /* DefaultKeyMappings.plist */; }; AB2F3B7F15CF9C6000858373 /* DefaultUserPrefs.plist in Resources */ = {isa = PBXBuildFile; fileRef = ABBC0F8C1394B1AA0028B6BD /* DefaultUserPrefs.plist */; }; @@ -212,7 +220,7 @@ AB2F3C2115CF9C6000858373 /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; AB2F3C2215CF9C6000858373 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; }; AB2F3C2415CF9C6000858373 /* cocoa_input.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104111346652500AF11D1 /* cocoa_input.mm */; }; - AB2F3C2515CF9C6000858373 /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; + AB2F3C2515CF9C6000858373 /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* mic_ext.cpp */; }; AB2F3C2615CF9C6000858373 /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; AB2F3C2715CF9C6000858373 /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; AB2F3C2815CF9C6000858373 /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; @@ -406,7 +414,7 @@ AB711F521481C35F009011C8 /* Timestretcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF9B1345ACFA00AF11D1 /* Timestretcher.cpp */; }; AB711F5C1481C35F009011C8 /* datetime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF1F1345ACBF00AF11D1 /* datetime.cpp */; }; AB711F5D1481C35F009011C8 /* fs-linux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEB21345AC8400AF11D1 /* fs-linux.cpp */; }; - AB711F5E1481C35F009011C8 /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; + AB711F5E1481C35F009011C8 /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* mic_ext.cpp */; }; AB711F5F1481C35F009011C8 /* OGLRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEC11345AC8400AF11D1 /* OGLRender.cpp */; }; AB711F601481C35F009011C8 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; }; AB711F611481C35F009011C8 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE670251415DE6C00E8E4C9 /* tinystr.cpp */; }; @@ -579,7 +587,7 @@ AB73AA0F1507C9F500A310C8 /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; AB73AA101507C9F500A310C8 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; }; AB73AA121507C9F500A310C8 /* cocoa_input.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104111346652500AF11D1 /* cocoa_input.mm */; }; - AB73AA131507C9F500A310C8 /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; + AB73AA131507C9F500A310C8 /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* mic_ext.cpp */; }; AB73AA141507C9F500A310C8 /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; AB73AA151507C9F500A310C8 /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; AB73AA161507C9F500A310C8 /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; @@ -770,7 +778,7 @@ ABAD101715ACE7A00000EC47 /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; ABAD101815ACE7A00000EC47 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; }; ABAD101A15ACE7A00000EC47 /* cocoa_input.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104111346652500AF11D1 /* cocoa_input.mm */; }; - ABAD101B15ACE7A00000EC47 /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; + ABAD101B15ACE7A00000EC47 /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* mic_ext.cpp */; }; ABAD101C15ACE7A00000EC47 /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; ABAD101D15ACE7A00000EC47 /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; ABAD101E15ACE7A00000EC47 /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; @@ -931,6 +939,9 @@ AB0F29A514BE7213009ABC6F /* Icon_Speaker_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Speaker_420x420.png; path = images/Icon_Speaker_420x420.png; sourceTree = ""; }; AB213D43170CB141006DDB0F /* InputProfileController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputProfileController.h; sourceTree = ""; }; AB213D44170CB141006DDB0F /* InputProfileController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InputProfileController.mm; sourceTree = ""; }; + AB213E981710D074006DDB0F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + AB2145211714DFF4006DDB0F /* audiosamplegenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiosamplegenerator.h; sourceTree = ""; }; + AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiosamplegenerator.cpp; sourceTree = ""; }; AB2F3C4515CF9C6000858373 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; }; AB2F56EE1704C86900E28885 /* utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utilities.h; sourceTree = ""; }; AB2F56EF1704C86900E28885 /* utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utilities.c; sourceTree = ""; }; @@ -1202,8 +1213,8 @@ ABD1FF7A1345ACFA00AF11D1 /* SndOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SndOut.cpp; sourceTree = ""; }; ABD1FF7B1345ACFA00AF11D1 /* SndOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SndOut.h; sourceTree = ""; }; ABD1FF9B1345ACFA00AF11D1 /* Timestretcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timestretcher.cpp; sourceTree = ""; }; - ABD9A46313DB99B300777194 /* cocoa_mic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_mic.h; sourceTree = ""; }; - ABD9A46413DB99B300777194 /* cocoa_mic.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_mic.mm; sourceTree = ""; }; + ABD9A46313DB99B300777194 /* mic_ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mic_ext.h; sourceTree = ""; }; + ABD9A46413DB99B300777194 /* mic_ext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mic_ext.cpp; sourceTree = ""; }; ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = ""; }; ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = ""; }; ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = ""; }; @@ -1313,6 +1324,7 @@ AB2F3C3F15CF9C6000858373 /* IOKit.framework in Frameworks */, AB2F3C4015CF9C6000858373 /* OpenGL.framework in Frameworks */, AB2F3C4115CF9C6000858373 /* libz.dylib in Frameworks */, + AB213EC41710D0A0006DDB0F /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1328,6 +1340,7 @@ AB711F7B1481C35F009011C8 /* IOKit.framework in Frameworks */, AB711F761481C35F009011C8 /* OpenGL.framework in Frameworks */, ABC3AFCF14B8D16700D5B13D /* libz.dylib in Frameworks */, + AB213E991710D074006DDB0F /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1343,6 +1356,7 @@ AB73AA2D1507C9F500A310C8 /* IOKit.framework in Frameworks */, AB73AA2E1507C9F500A310C8 /* OpenGL.framework in Frameworks */, AB73AA2F1507C9F500A310C8 /* libz.dylib in Frameworks */, + AB213EC61710D0A1006DDB0F /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1358,6 +1372,7 @@ ABAD104315ACE7A00000EC47 /* IOKit.framework in Frameworks */, ABAD104415ACE7A00000EC47 /* OpenGL.framework in Frameworks */, ABAD104515ACE7A00000EC47 /* libz.dylib in Frameworks */, + AB213EC51710D0A1006DDB0F /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1369,9 +1384,12 @@ children = ( AB3ACB6514C2361100D7D192 /* userinterface */, AB2F56EF1704C86900E28885 /* utilities.c */, + AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */, ABD0A5341501AA5A0074A094 /* coreaudiosound.cpp */, + ABD9A46413DB99B300777194 /* mic_ext.cpp */, ABD0A5351501AA5A0074A094 /* ringbuffer.cpp */, ABD104141346652500AF11D1 /* sndOSX.cpp */, + AB2145211714DFF4006DDB0F /* audiosamplegenerator.h */, ABA6574914511EC90077E5E9 /* cocoa_cheat.h */, ABD103FE1346652500AF11D1 /* cocoa_core.h */, AB58F32B1364F44B0074C376 /* cocoa_file.h */, @@ -1379,12 +1397,12 @@ AB9971CE134EDA0800531BA7 /* cocoa_globals.h */, AB6A198116CAD66900384EED /* cocoa_GPU.h */, ABD103FF1346652500AF11D1 /* cocoa_input.h */, - ABD9A46313DB99B300777194 /* cocoa_mic.h */, AB3E34C7134AF4500056477A /* cocoa_output.h */, ABD104001346652500AF11D1 /* cocoa_rom.h */, AB80E050142BC4FA00A52038 /* cocoa_util.h */, ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */, ABD0A5361501AA5A0074A094 /* coreaudiosound.h */, + ABD9A46313DB99B300777194 /* mic_ext.h */, ABD0A5371501AA5A0074A094 /* ringbuffer.h */, ABD104011346652500AF11D1 /* sndOSX.h */, AB2F56EE1704C86900E28885 /* utilities.h */, @@ -1394,7 +1412,6 @@ ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */, AB6A198216CAD66900384EED /* cocoa_GPU.mm */, ABD104111346652500AF11D1 /* cocoa_input.mm */, - ABD9A46413DB99B300777194 /* cocoa_mic.mm */, AB3E34C8134AF4500056477A /* cocoa_output.mm */, ABD104131346652500AF11D1 /* cocoa_rom.mm */, AB80E04C142BC4A800A52038 /* cocoa_util.mm */, @@ -1408,6 +1425,7 @@ children = ( AB97C553169646D1002AC11B /* Accelerate.framework */, 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + AB213E981710D074006DDB0F /* AudioToolbox.framework */, ABC570D0134431CE00E7B0B1 /* AudioUnit.framework */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 29B97325FDCFA39411CA2CEA /* Foundation.framework */, @@ -2623,7 +2641,7 @@ AB2F3C2115CF9C6000858373 /* cocoa_file.mm in Sources */, AB2F3C2215CF9C6000858373 /* cocoa_firmware.mm in Sources */, AB2F3C2415CF9C6000858373 /* cocoa_input.mm in Sources */, - AB2F3C2515CF9C6000858373 /* cocoa_mic.mm in Sources */, + AB2F3C2515CF9C6000858373 /* mic_ext.cpp in Sources */, AB2F3C2615CF9C6000858373 /* cocoa_output.mm in Sources */, AB2F3C2715CF9C6000858373 /* cocoa_rom.mm in Sources */, AB2F3C2815CF9C6000858373 /* cocoa_util.mm in Sources */, @@ -2659,6 +2677,7 @@ AB4C4C5216F55C64002E07CD /* WavFile.cpp in Sources */, AB2F56F11704C86900E28885 /* utilities.c in Sources */, AB213D46170CB141006DDB0F /* InputProfileController.mm in Sources */, + AB2145241714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2752,7 +2771,7 @@ AB711F4E1481C35F009011C8 /* cocoa_file.mm in Sources */, AB711F601481C35F009011C8 /* cocoa_firmware.mm in Sources */, AB711F461481C35F009011C8 /* cocoa_input.mm in Sources */, - AB711F5E1481C35F009011C8 /* cocoa_mic.mm in Sources */, + AB711F5E1481C35F009011C8 /* mic_ext.cpp in Sources */, AB711F4C1481C35F009011C8 /* cocoa_output.mm in Sources */, AB711F481481C35F009011C8 /* cocoa_rom.mm in Sources */, AB711F6C1481C35F009011C8 /* cocoa_util.mm in Sources */, @@ -2817,6 +2836,7 @@ AB4C4C4816F55C64002E07CD /* WavFile.cpp in Sources */, AB2F56F01704C86900E28885 /* utilities.c in Sources */, AB213D48170CB141006DDB0F /* InputProfileController.mm in Sources */, + AB2145261714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2909,7 +2929,7 @@ AB73AA0F1507C9F500A310C8 /* cocoa_file.mm in Sources */, AB73AA101507C9F500A310C8 /* cocoa_firmware.mm in Sources */, AB73AA121507C9F500A310C8 /* cocoa_input.mm in Sources */, - AB73AA131507C9F500A310C8 /* cocoa_mic.mm in Sources */, + AB73AA131507C9F500A310C8 /* mic_ext.cpp in Sources */, AB73AA141507C9F500A310C8 /* cocoa_output.mm in Sources */, AB73AA151507C9F500A310C8 /* cocoa_rom.mm in Sources */, AB73AA161507C9F500A310C8 /* cocoa_util.mm in Sources */, @@ -2975,6 +2995,7 @@ AB4C4C6616F55C64002E07CD /* WavFile.cpp in Sources */, AB2F56F31704C86900E28885 /* utilities.c in Sources */, AB213D45170CB141006DDB0F /* InputProfileController.mm in Sources */, + AB2145251714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3067,7 +3088,7 @@ ABAD101715ACE7A00000EC47 /* cocoa_file.mm in Sources */, ABAD101815ACE7A00000EC47 /* cocoa_firmware.mm in Sources */, ABAD101A15ACE7A00000EC47 /* cocoa_input.mm in Sources */, - ABAD101B15ACE7A00000EC47 /* cocoa_mic.mm in Sources */, + ABAD101B15ACE7A00000EC47 /* mic_ext.cpp in Sources */, ABAD101C15ACE7A00000EC47 /* cocoa_output.mm in Sources */, ABAD101D15ACE7A00000EC47 /* cocoa_rom.mm in Sources */, ABAD101E15ACE7A00000EC47 /* cocoa_util.mm in Sources */, @@ -3103,6 +3124,7 @@ AB4C4C5C16F55C64002E07CD /* WavFile.cpp in Sources */, AB2F56F21704C86900E28885 /* utilities.c in Sources */, AB213D47170CB141006DDB0F /* InputProfileController.mm in Sources */, + AB2145231714DFF4006DDB0F /* audiosamplegenerator.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj index 5e5f6e865..d8cb78325 100644 --- a/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj @@ -354,7 +354,6 @@ AB796D4C15CDCBA200C59155 /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; AB796D4D15CDCBA200C59155 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; }; AB796D4F15CDCBA200C59155 /* cocoa_input.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104111346652500AF11D1 /* cocoa_input.mm */; }; - AB796D5015CDCBA200C59155 /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; AB796D5115CDCBA200C59155 /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; AB796D5215CDCBA200C59155 /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; AB796D5315CDCBA200C59155 /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; @@ -391,6 +390,9 @@ AB901BDE1420706100348EEC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB901BDD1420706100348EEC /* Localizable.strings */; }; AB91D46B13BD013800462471 /* fs-linux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEB21345AC8400AF11D1 /* fs-linux.cpp */; }; ABA6574B14511EC90077E5E9 /* cocoa_cheat.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */; }; + ABACB8DC1710B621003B845D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABACB8DB1710B621003B845D /* AudioToolbox.framework */; }; + ABACB8DD1710B656003B845D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABACB8DB1710B621003B845D /* AudioToolbox.framework */; }; + ABACB8DE1710B65F003B845D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABACB8DB1710B621003B845D /* AudioToolbox.framework */; }; ABAD3E7113AF1D6D00502E1E /* AAFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABAD3E6513AF1D6D00502E1E /* AAFilter.cpp */; }; ABAD3E7413AF1D6D00502E1E /* FIFOSampleBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABAD3E6813AF1D6D00502E1E /* FIFOSampleBuffer.cpp */; }; ABAD3E7513AF1D6D00502E1E /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABAD3E6913AF1D6D00502E1E /* FIRFilter.cpp */; }; @@ -412,7 +414,6 @@ ABB3C6701501C04F00E0C22E /* videofilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */; }; ABB3C6711501C04F00E0C22E /* cocoa_core.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104121346652500AF11D1 /* cocoa_core.mm */; }; ABB3C6721501C04F00E0C22E /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; - ABB3C6731501C04F00E0C22E /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; ABB3C6741501C04F00E0C22E /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; ABB3C6751501C04F00E0C22E /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; ABB3C6761501C04F00E0C22E /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; @@ -530,6 +531,14 @@ ABD1041E1346652500AF11D1 /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; ABD1041F1346652500AF11D1 /* sndOSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD104141346652500AF11D1 /* sndOSX.cpp */; }; ABD104281346653B00AF11D1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ABD104271346653B00AF11D1 /* main.m */; }; + ABD10AE71715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE51715FCDD00B5729D /* audiosamplegenerator.cpp */; }; + ABD10AE81715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE51715FCDD00B5729D /* audiosamplegenerator.cpp */; }; + ABD10AE91715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE51715FCDD00B5729D /* audiosamplegenerator.cpp */; }; + ABD10AEA1715FCDD00B5729D /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE61715FCDD00B5729D /* mic_ext.cpp */; }; + ABD10AEB1715FCDD00B5729D /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE61715FCDD00B5729D /* mic_ext.cpp */; }; + ABD10AEC1715FCDD00B5729D /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE61715FCDD00B5729D /* mic_ext.cpp */; }; + ABD10AED17160C9300B5729D /* ringbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B9E601501A78000464647 /* ringbuffer.cpp */; }; + ABD10AEE17160CDD00B5729D /* cocoa_input.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104111346652500AF11D1 /* cocoa_input.mm */; }; ABD1FED01345AC8400AF11D1 /* addons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEA11345AC8400AF11D1 /* addons.cpp */; }; ABD1FED21345AC8400AF11D1 /* arm_instructions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEA31345AC8400AF11D1 /* arm_instructions.cpp */; }; ABD1FED31345AC8400AF11D1 /* armcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEA41345AC8400AF11D1 /* armcpu.cpp */; }; @@ -598,7 +607,6 @@ ABD1FF681345ACBF00AF11D1 /* vfat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF4F1345ACBF00AF11D1 /* vfat.cpp */; }; ABD1FF691345ACBF00AF11D1 /* xstring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF511345ACBF00AF11D1 /* xstring.cpp */; }; ABD1FF9F1345ACFA00AF11D1 /* metaspu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF771345ACFA00AF11D1 /* metaspu.cpp */; }; - ABD9A46513DB99B300777194 /* cocoa_mic.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD9A46413DB99B300777194 /* cocoa_mic.mm */; }; ABE5DE95143F781900835AD8 /* videofilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */; }; ABE5DFE5143FB1DA00835AD8 /* cocoa_videofilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */; }; ABE6702B1415DE6C00E8E4C9 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE670251415DE6C00E8E4C9 /* tinystr.cpp */; }; @@ -809,6 +817,7 @@ AB9971CE134EDA0800531BA7 /* cocoa_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_globals.h; sourceTree = ""; }; ABA6574914511EC90077E5E9 /* cocoa_cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_cheat.h; sourceTree = ""; }; ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_cheat.mm; sourceTree = ""; }; + ABACB8DB1710B621003B845D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; ABAD3E5913AF1D6D00502E1E /* AAFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AAFilter.h; sourceTree = ""; }; ABAD3E5A13AF1D6D00502E1E /* BPMDetect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BPMDetect.h; sourceTree = ""; }; ABAD3E5B13AF1D6D00502E1E /* cpu_detect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu_detect.h; sourceTree = ""; }; @@ -862,6 +871,10 @@ ABD104141346652500AF11D1 /* sndOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sndOSX.cpp; sourceTree = ""; }; ABD104271346653B00AF11D1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; ABD10452134666DD00AF11D1 /* DeSmuME_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeSmuME_Prefix.pch; sourceTree = ""; }; + ABD10AE31715FCDD00B5729D /* audiosamplegenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiosamplegenerator.h; sourceTree = SOURCE_ROOT; }; + ABD10AE41715FCDD00B5729D /* mic_ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mic_ext.h; sourceTree = SOURCE_ROOT; }; + ABD10AE51715FCDD00B5729D /* audiosamplegenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiosamplegenerator.cpp; sourceTree = SOURCE_ROOT; }; + ABD10AE61715FCDD00B5729D /* mic_ext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mic_ext.cpp; sourceTree = SOURCE_ROOT; }; ABD1FE6B1345AC8400AF11D1 /* addons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = addons.h; path = ../addons.h; sourceTree = SOURCE_ROOT; }; ABD1FE6C1345AC8400AF11D1 /* agg2d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = agg2d.h; path = ../agg2d.h; sourceTree = SOURCE_ROOT; }; ABD1FE6D1345AC8400AF11D1 /* aggdraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aggdraw.h; path = ../aggdraw.h; sourceTree = SOURCE_ROOT; }; @@ -1029,8 +1042,6 @@ ABD1FF7A1345ACFA00AF11D1 /* SndOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SndOut.cpp; sourceTree = ""; }; ABD1FF7B1345ACFA00AF11D1 /* SndOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SndOut.h; sourceTree = ""; }; ABD1FF9B1345ACFA00AF11D1 /* Timestretcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timestretcher.cpp; sourceTree = ""; }; - ABD9A46313DB99B300777194 /* cocoa_mic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_mic.h; sourceTree = ""; }; - ABD9A46413DB99B300777194 /* cocoa_mic.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_mic.mm; sourceTree = ""; }; ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = ""; }; ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = ""; }; ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = ""; }; @@ -1068,6 +1079,7 @@ files = ( AB4FCEBE1692AB82000F498F /* Accelerate.framework in Frameworks */, ABC5720D1344346600E7B0B1 /* AppKit.framework in Frameworks */, + ABACB8DD1710B656003B845D /* AudioToolbox.framework in Frameworks */, ABC570D1134431CE00E7B0B1 /* AudioUnit.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, ABC572101344347000E7B0B1 /* Foundation.framework in Frameworks */, @@ -1083,6 +1095,7 @@ files = ( AB4FCEBD1692AB82000F498F /* Accelerate.framework in Frameworks */, AB796D6615CDCBA200C59155 /* AppKit.framework in Frameworks */, + ABACB8DC1710B621003B845D /* AudioToolbox.framework in Frameworks */, AB796D6715CDCBA200C59155 /* AudioUnit.framework in Frameworks */, AB796D6815CDCBA200C59155 /* Cocoa.framework in Frameworks */, AB796D6915CDCBA200C59155 /* Foundation.framework in Frameworks */, @@ -1098,6 +1111,7 @@ files = ( AB4FCEBF1692AB82000F498F /* Accelerate.framework in Frameworks */, ABB3C6641501BF8A00E0C22E /* AppKit.framework in Frameworks */, + ABACB8DE1710B65F003B845D /* AudioToolbox.framework in Frameworks */, ABB3C6651501BF8A00E0C22E /* AudioUnit.framework in Frameworks */, ABB3C6661501BF8A00E0C22E /* Cocoa.framework in Frameworks */, ABB3C6671501BF8A00E0C22E /* Foundation.framework in Frameworks */, @@ -1116,10 +1130,13 @@ ABB3C63A1501BB8300E0C22E /* openemu */, AB3ACB6514C2361100D7D192 /* userinterface */, AB82445A1704AE9A00B8EE20 /* utilities.c */, + ABD10AE51715FCDD00B5729D /* audiosamplegenerator.cpp */, AB1B9E5F1501A78000464647 /* coreaudiosound.cpp */, AB23567216C2F6F400DA782E /* macosx_10_5_compat.cpp */, + ABD10AE61715FCDD00B5729D /* mic_ext.cpp */, AB1B9E601501A78000464647 /* ringbuffer.cpp */, ABD104141346652500AF11D1 /* sndOSX.cpp */, + ABD10AE31715FCDD00B5729D /* audiosamplegenerator.h */, ABA6574914511EC90077E5E9 /* cocoa_cheat.h */, ABD103FE1346652500AF11D1 /* cocoa_core.h */, AB58F32B1364F44B0074C376 /* cocoa_file.h */, @@ -1127,12 +1144,12 @@ AB9971CE134EDA0800531BA7 /* cocoa_globals.h */, AB3A656416CC5442001F5D4A /* cocoa_GPU.h */, ABD103FF1346652500AF11D1 /* cocoa_input.h */, - ABD9A46313DB99B300777194 /* cocoa_mic.h */, AB3E34C7134AF4500056477A /* cocoa_output.h */, ABD104001346652500AF11D1 /* cocoa_rom.h */, AB80E050142BC4FA00A52038 /* cocoa_util.h */, ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */, AB1B9E611501A78000464647 /* coreaudiosound.h */, + ABD10AE41715FCDD00B5729D /* mic_ext.h */, AB1B9E621501A78000464647 /* ringbuffer.h */, ABD104011346652500AF11D1 /* sndOSX.h */, AB82445E1704AEC400B8EE20 /* utilities.h */, @@ -1142,7 +1159,6 @@ ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */, AB3A656016CC5438001F5D4A /* cocoa_GPU.mm */, ABD104111346652500AF11D1 /* cocoa_input.mm */, - ABD9A46413DB99B300777194 /* cocoa_mic.mm */, AB3E34C8134AF4500056477A /* cocoa_output.mm */, ABD104131346652500AF11D1 /* cocoa_rom.mm */, AB80E04C142BC4A800A52038 /* cocoa_util.mm */, @@ -1156,6 +1172,7 @@ children = ( AB4FCEBC1692AB82000F498F /* Accelerate.framework */, 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + ABACB8DB1710B621003B845D /* AudioToolbox.framework */, ABC570D0134431CE00E7B0B1 /* AudioUnit.framework */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 29B97325FDCFA39411CA2CEA /* Foundation.framework */, @@ -2197,7 +2214,6 @@ AB58F32D1364F44B0074C376 /* cocoa_file.mm in Sources */, ABE7F53E13EE1C7900FD3A71 /* cocoa_firmware.mm in Sources */, ABD1041C1346652500AF11D1 /* cocoa_input.mm in Sources */, - ABD9A46513DB99B300777194 /* cocoa_mic.mm in Sources */, AB3E34C9134AF4500056477A /* cocoa_output.mm in Sources */, ABD1041E1346652500AF11D1 /* cocoa_rom.mm in Sources */, AB80E04D142BC4A800A52038 /* cocoa_util.mm in Sources */, @@ -2255,6 +2271,8 @@ AB29B33216D4BEBF000EF671 /* InputManager.mm in Sources */, AB82445C1704AE9A00B8EE20 /* utilities.c in Sources */, AB01005F170D07B000D70FBE /* InputProfileController.mm in Sources */, + ABD10AE81715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */, + ABD10AEB1715FCDD00B5729D /* mic_ext.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2358,7 +2376,6 @@ AB796D4C15CDCBA200C59155 /* cocoa_file.mm in Sources */, AB796D4D15CDCBA200C59155 /* cocoa_firmware.mm in Sources */, AB796D4F15CDCBA200C59155 /* cocoa_input.mm in Sources */, - AB796D5015CDCBA200C59155 /* cocoa_mic.mm in Sources */, AB796D5115CDCBA200C59155 /* cocoa_output.mm in Sources */, AB796D5215CDCBA200C59155 /* cocoa_rom.mm in Sources */, AB796D5315CDCBA200C59155 /* cocoa_util.mm in Sources */, @@ -2414,6 +2431,8 @@ AB29B33116D4BEBF000EF671 /* InputManager.mm in Sources */, AB82445B1704AE9A00B8EE20 /* utilities.c in Sources */, AB01005E170D07B000D70FBE /* InputProfileController.mm in Sources */, + ABD10AE71715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */, + ABD10AEA1715FCDD00B5729D /* mic_ext.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2426,7 +2445,6 @@ ABB3C6701501C04F00E0C22E /* videofilter.cpp in Sources */, ABB3C6711501C04F00E0C22E /* cocoa_core.mm in Sources */, ABB3C6721501C04F00E0C22E /* cocoa_file.mm in Sources */, - ABB3C6731501C04F00E0C22E /* cocoa_mic.mm in Sources */, ABB3C6741501C04F00E0C22E /* cocoa_output.mm in Sources */, ABB3C6751501C04F00E0C22E /* cocoa_rom.mm in Sources */, ABB3C6761501C04F00E0C22E /* cocoa_util.mm in Sources */, @@ -2561,6 +2579,10 @@ AB3A656316CC5438001F5D4A /* cocoa_GPU.mm in Sources */, AB82445D1704AE9A00B8EE20 /* utilities.c in Sources */, AB010060170D07B000D70FBE /* InputProfileController.mm in Sources */, + ABD10AE91715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */, + ABD10AEC1715FCDD00B5729D /* mic_ext.cpp in Sources */, + ABD10AED17160C9300B5729D /* ringbuffer.cpp in Sources */, + ABD10AEE17160CDD00B5729D /* cocoa_input.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/desmume/src/cocoa/DefaultKeyMappings.plist b/desmume/src/cocoa/DefaultKeyMappings.plist index 587512753..94419cfb7 100644 --- a/desmume/src/cocoa/DefaultKeyMappings.plist +++ b/desmume/src/cocoa/DefaultKeyMappings.plist @@ -256,7 +256,9 @@ inputSettingsSummary Internal Noise Samples intValue1 - 1 + 1 + floatValue0 + 250 Lid @@ -371,7 +373,7 @@ inputSettingsSummary 0.50x Speed floatValue0 - 0.5 + 0.5 deviceInfoSummary diff --git a/desmume/src/cocoa/audiosamplegenerator.cpp b/desmume/src/cocoa/audiosamplegenerator.cpp new file mode 100644 index 000000000..eb783dc67 --- /dev/null +++ b/desmume/src/cocoa/audiosamplegenerator.cpp @@ -0,0 +1,161 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . + */ + +#ifdef __APPLE__ + #include + #include "utilities.h" +#endif // __APPLE__ + +#include "audiosamplegenerator.h" +#include + +#define NUM_INTERNAL_NOISE_SAMPLES 32 + +static const u8 noiseSample[NUM_INTERNAL_NOISE_SAMPLES] = +{ + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0x8E, 0xFF, + 0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01 +}; + +AudioSampleBlockGenerator::AudioSampleBlockGenerator(const u8 *audioBuffer, const size_t sampleCount) +{ + _buffer = (u8 *)malloc(sampleCount * sizeof(u8)); + _sampleCount = sampleCount; + _samplePosition = 0; + memcpy(_buffer, audioBuffer, _sampleCount * sizeof(u8)); +} + +AudioSampleBlockGenerator::~AudioSampleBlockGenerator() +{ + free(this->_buffer); + this->_buffer = NULL; +} + +u8* AudioSampleBlockGenerator::allocate(const size_t sampleCount) +{ + if (this->_buffer != NULL) + { + free(this->_buffer); + } + + this->_buffer = (u8 *)malloc(sampleCount * sizeof(u8)); + this->_sampleCount = sampleCount; + this->_samplePosition = 0; + memset(this->_buffer, MIC_NULL_SAMPLE_VALUE, this->_sampleCount * sizeof(u8)); + + return this->_buffer; +} + +u8 AudioSampleBlockGenerator::generateSample() +{ + if (this->_samplePosition >= this->_sampleCount) + { + this->_samplePosition = 0; + } + + return this->_buffer[_samplePosition++]; +} + +u8* AudioSampleBlockGenerator::getBuffer() const +{ + return this->_buffer; +} + +size_t AudioSampleBlockGenerator::getSampleCount() const +{ + return this->_sampleCount; +} + +size_t AudioSampleBlockGenerator::getSamplePosition() const +{ + return this->_samplePosition; +} + +void AudioSampleBlockGenerator::setSamplePosition(size_t thePosition) +{ + this->_samplePosition = thePosition % this->_sampleCount; +} + +InternalNoiseGenerator::InternalNoiseGenerator() +{ + _buffer = (u8 *)malloc(NUM_INTERNAL_NOISE_SAMPLES * sizeof(u8)); + _sampleCount = NUM_INTERNAL_NOISE_SAMPLES; + _samplePosition = 0; + memcpy(_buffer, noiseSample, _sampleCount * sizeof(u8)); +} + +u8 WhiteNoiseGenerator::generateSample() +{ +#ifdef __APPLE__ + #ifdef MAC_OS_X_VERSION_10_7 + if (IsOSXVersionSupported(10, 7, 0)) + { + return (u8)(arc4random_uniform(0x00000080) & 0x7F); + } + return (u8)((arc4random() % 0x00000080) & 0x7F); + #else + return (u8)((arc4random() % 0x00000080) & 0x7F); + #endif +#else + return (u8)(rand() & 0x7F); +#endif +} + +SineWaveGenerator::SineWaveGenerator(const double freq, const double sampleRate) +{ + _frequency = freq; + _sampleRate = sampleRate; + _cyclePosition = 0.0; +} + +u8 SineWaveGenerator::generateSample() +{ + const u8 sampleValue = (u8)(63.0 * sin(2.0 * M_PI * this->_cyclePosition)) + MIC_NULL_SAMPLE_VALUE; + this->_cyclePosition += (this->_frequency / this->_sampleRate); + + return sampleValue; +} + +double SineWaveGenerator::getFrequency() const +{ + return this->_frequency; +} + +void SineWaveGenerator::setFrequency(double freq) +{ + this->_frequency = freq; +} + +double SineWaveGenerator::getSampleRate() const +{ + return this->_sampleRate; +} + +void SineWaveGenerator::setSampleRate(double sampleRate) +{ + this->_sampleRate = sampleRate; +} + +double SineWaveGenerator::getCyclePosition() const +{ + return this->_cyclePosition; +} + +void SineWaveGenerator::setCyclePosition(double thePosition) +{ + this->_cyclePosition = thePosition; +} diff --git a/desmume/src/cocoa/audiosamplegenerator.h b/desmume/src/cocoa/audiosamplegenerator.h new file mode 100644 index 000000000..717f7cd06 --- /dev/null +++ b/desmume/src/cocoa/audiosamplegenerator.h @@ -0,0 +1,118 @@ +/* + Copyright (C) 2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . + */ + +#ifndef _AUDIO_SAMPLE_GENERATOR_ +#define _AUDIO_SAMPLE_GENERATOR_ + +#include +#include "types.h" + +#define MIC_NULL_SAMPLE_VALUE 64 + + +class AudioGenerator +{ +public: + AudioGenerator() {}; + virtual ~AudioGenerator() {}; + + virtual size_t generateSampleBlock(size_t sampleCount, u8 *outBuffer) + { + if (outBuffer == NULL) + { + return 0; + } + + for (u8 *i = outBuffer; i < outBuffer + sampleCount; i++) + { + *i = this->generateSample(); + } + + return sampleCount; + } + + virtual u8 generateSample() + { + return MIC_NULL_SAMPLE_VALUE; + } +}; + +class NullGenerator : public AudioGenerator {}; + +class AudioSampleBlockGenerator : public AudioGenerator +{ +protected: + u8 *_buffer; + size_t _sampleCount; + size_t _samplePosition; + +public: + AudioSampleBlockGenerator() + : _buffer(NULL) + , _sampleCount(0) + , _samplePosition(0) + {}; + AudioSampleBlockGenerator(const u8 *audioBuffer, const size_t sampleCount); + ~AudioSampleBlockGenerator(); + + u8* allocate(const size_t sampleCount); + u8* getBuffer() const; + size_t getSampleCount() const; + size_t getSamplePosition() const; + void setSamplePosition(size_t thePosition); + + virtual u8 generateSample(); +}; + +class InternalNoiseGenerator : public AudioSampleBlockGenerator +{ +public: + InternalNoiseGenerator(); +}; + +class WhiteNoiseGenerator : public AudioGenerator +{ +public: + virtual u8 generateSample(); +}; + +class SineWaveGenerator : public AudioGenerator +{ +protected: + double _frequency; + double _sampleRate; + double _cyclePosition; + +public: + SineWaveGenerator() + : _frequency(250.0) + , _sampleRate(44100.0) + , _cyclePosition(0.0) + {}; + SineWaveGenerator(const double freq, const double sampleRate); + + double getFrequency() const; + void setFrequency(double freq); + double getSampleRate() const; + void setSampleRate(double sampleRate); + double getCyclePosition() const; + void setCyclePosition(double thePosition); + + virtual u8 generateSample(); +}; + +#endif // _AUDIO_SAMPLE_GENERATOR_ diff --git a/desmume/src/cocoa/cocoa_globals.h b/desmume/src/cocoa/cocoa_globals.h index 59d8b3fb5..5b739e489 100644 --- a/desmume/src/cocoa/cocoa_globals.h +++ b/desmume/src/cocoa/cocoa_globals.h @@ -109,7 +109,9 @@ #define NSSTRING_INPUTPREF_USE_DEVICE_COORDINATES NSLocalizedString(@"Use Device Coordinates", nil) #define NSSTRING_INPUTPREF_MIC_NONE NSLocalizedString(@"None", nil) #define NSSTRING_INPUTPREF_MIC_INTERNAL_NOISE NSLocalizedString(@"Internal Noise Samples", nil) +#define NSSTRING_INPUTPREF_MIC_AUDIO_FILE_NONE_SELECTED NSLocalizedString(@"No audio file selected.", nil) #define NSSTRING_INPUTPREF_MIC_WHITE_NOISE NSLocalizedString(@"White Noise", nil) +#define NSSTRING_INPUTPREF_MIC_SINE_WAVE NSLocalizedString(@"%1.1f Hz Sine Wave", nil) #define NSSTRING_INPUTPREF_SPEED_SCALAR NSLocalizedString(@"%1.2fx Speed", nil) #define NSSTRING_INPUTPREF_GPU_STATE_ALL_MAIN NSLocalizedString(@"Main GPU - All Layers", nil) #define NSSTRING_INPUTPREF_GPU_STATE_ALL_SUB NSLocalizedString(@"Sub GPU - All Layers", nil) @@ -205,10 +207,8 @@ #define ROMINFO_GAME_CODE_LENGTH 4 #define ROMINFO_GAME_BANNER_LENGTH 128 -#define MIC_NULL_SAMPLE_VALUE 0 #define MIC_SAMPLE_RATE 16000 -#define MIC_MAX_BUFFER_SAMPLES 320 -#define MIC_BUFFER_SIZE (sizeof(UInt8) * MIC_MAX_BUFFER_SAMPLES) +#define MIC_MAX_BUFFER_SAMPLES (MIC_SAMPLE_RATE / DS_FRAMES_PER_SECOND) #define COCOA_DIALOG_CANCEL 0 #define COCOA_DIALOG_DEFAULT 1 @@ -461,7 +461,8 @@ enum { MICMODE_NONE = 0, MICMODE_INTERNAL_NOISE, - MICMODE_SOUND_FILE, + MICMODE_AUDIO_FILE, MICMODE_WHITE_NOISE, - MICMODE_PHYSICAL + MICMODE_PHYSICAL, + MICMODE_SINE_WAVE }; diff --git a/desmume/src/cocoa/cocoa_input.h b/desmume/src/cocoa/cocoa_input.h index 73304c507..3b33a8941 100644 --- a/desmume/src/cocoa/cocoa_input.h +++ b/desmume/src/cocoa/cocoa_input.h @@ -18,8 +18,8 @@ #import #include - -@class CocoaDSMic; +#include "mic_ext.h" +#undef BOOL enum { @@ -46,20 +46,21 @@ enum @interface CocoaDSController : NSObject { - CocoaDSMic *cdsMic; + NSInteger micMode; NSPoint touchLocation; bool controllerState[DSControllerState_StatesCount]; + AudioSampleBlockGenerator *selectedAudioFileGenerator; OSSpinLock spinlockControllerState; } -@property (retain) CocoaDSMic *cdsMic; - -- (id) initWithMic:(CocoaDSMic *)theMic; +@property (assign) NSInteger micMode; +@property (assign) AudioSampleBlockGenerator *selectedAudioFileGenerator; - (void) setControllerState:(BOOL)theState controlID:(const NSUInteger)controlID; - (void) setTouchState:(BOOL)theState location:(const NSPoint)theLocation; - (void) setMicrophoneState:(BOOL)theState inputMode:(const NSInteger)inputMode; +- (void) setSineWaveGeneratorFrequency:(const double)freq; - (void) flush; @end diff --git a/desmume/src/cocoa/cocoa_input.mm b/desmume/src/cocoa/cocoa_input.mm index d4c696e86..a2536f98f 100644 --- a/desmume/src/cocoa/cocoa_input.mm +++ b/desmume/src/cocoa/cocoa_input.mm @@ -17,9 +17,7 @@ */ #import "cocoa_input.h" - #import "cocoa_globals.h" -#import "cocoa_mic.h" #include "../NDSSystem.h" #undef BOOL @@ -27,14 +25,10 @@ @implementation CocoaDSController -@synthesize cdsMic; +@synthesize micMode; +@synthesize selectedAudioFileGenerator; - (id)init -{ - return [self initWithMic:nil]; -} - -- (id) initWithMic:(CocoaDSMic *)theMic { self = [super init]; if (self == nil) @@ -47,9 +41,9 @@ controllerState[i] = false; } - spinlockControllerState = OS_SPINLOCK_INIT; - - cdsMic = [theMic retain]; + spinlockControllerState = OS_SPINLOCK_INIT; + micMode = MICMODE_NONE; + selectedAudioFileGenerator = NULL; touchLocation = NSMakePoint(0.0f, 0.0f); return self; @@ -57,8 +51,6 @@ - (void)dealloc { - self.cdsMic = nil; - [super dealloc]; } @@ -86,17 +78,22 @@ { OSSpinLockLock(&spinlockControllerState); controllerState[DSControllerState_Microphone] = (theState) ? true : false; - self.cdsMic.mode = inputMode; + micMode = inputMode; OSSpinLockUnlock(&spinlockControllerState); } +- (void) setSineWaveGeneratorFrequency:(const double)freq +{ + sineWaveGenerator.setFrequency(freq); +} + - (void) flush { OSSpinLockLock(&spinlockControllerState); - NSPoint theLocation = touchLocation; - NSInteger micMode = cdsMic.mode; - bool flushedStates[DSControllerState_StatesCount] = {0}; + const NSPoint theLocation = touchLocation; + const NSInteger theMicMode = micMode; + static bool flushedStates[DSControllerState_StatesCount] = {0}; for (unsigned int i = 0; i < DSControllerState_StatesCount; i++) { @@ -105,8 +102,8 @@ OSSpinLockUnlock(&spinlockControllerState); - bool isTouchDown = flushedStates[DSControllerState_Touch]; - bool isMicPressed = flushedStates[DSControllerState_Microphone]; + const bool isTouchDown = flushedStates[DSControllerState_Touch]; + const bool isMicPressed = flushedStates[DSControllerState_Microphone]; // Setup the DS pad. NDS_setPad(flushedStates[DSControllerState_Right], @@ -135,26 +132,65 @@ } // Setup the DS mic. - NDS_setMic(isMicPressed); - - if (isMicPressed) + AudioGenerator *selectedGenerator = &nullSampleGenerator; + switch (theMicMode) { - if (micMode == MICMODE_NONE) + case MICMODE_INTERNAL_NOISE: + selectedGenerator = &internalNoiseGenerator; + break; + + case MICMODE_WHITE_NOISE: + selectedGenerator = &whiteNoiseGenerator; + break; + + case MICMODE_SINE_WAVE: + selectedGenerator = &sineWaveGenerator; + break; + + case MICMODE_AUDIO_FILE: + if (selectedAudioFileGenerator != NULL) + { + selectedGenerator = selectedAudioFileGenerator; + } + break; + + default: + break; + } + + NDS_setMic(isMicPressed); + if (!isMicPressed) + { + selectedGenerator = &nullSampleGenerator; + + internalNoiseGenerator.setSamplePosition(0); + sineWaveGenerator.setCyclePosition(0.0); + + if (selectedAudioFileGenerator != NULL) { - [cdsMic fillWithNullSamples]; + selectedAudioFileGenerator->setSamplePosition(0); } - else if (micMode == MICMODE_INTERNAL_NOISE) + } + + static const bool useBufferedSource = false; + Mic_SetUseBufferedSource(useBufferedSource); + if (useBufferedSource) + { + static u8 generatedSampleBuffer[(size_t)(MIC_MAX_BUFFER_SAMPLES + 0.5)] = {0}; + static const size_t requestedSamples = MIC_MAX_BUFFER_SAMPLES; + + const size_t availableSamples = micInputBuffer.getAvailableElements(); + if (availableSamples < requestedSamples) { - [cdsMic fillWithInternalNoise]; - } - else if (micMode == MICMODE_WHITE_NOISE) - { - [cdsMic fillWithWhiteNoise]; - } - else if (micMode == MICMODE_SOUND_FILE) - { - // TODO: Need to implement. Does nothing for now. + micInputBuffer.drop(requestedSamples - availableSamples); } + + selectedGenerator->generateSampleBlock(requestedSamples, generatedSampleBuffer); + micInputBuffer.write(generatedSampleBuffer, requestedSamples); + } + else + { + Mic_SetSelectedDirectSampleGenerator(selectedGenerator); } } diff --git a/desmume/src/cocoa/cocoa_mic.h b/desmume/src/cocoa/cocoa_mic.h deleted file mode 100644 index 5987a5b16..000000000 --- a/desmume/src/cocoa/cocoa_mic.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2011 Roger Manuel - Copyright (C) 2012 DeSmuME team - - This file is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the this software. If not, see . -*/ - -#import - - -#define NUM_INTERNAL_NOISE_SAMPLES 32 - -static const UInt8 noiseSample[NUM_INTERNAL_NOISE_SAMPLES] = -{ - 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0x8E, 0xFF, - 0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01 -}; - -@interface CocoaDSMic : NSObject -{ - UInt8 *buffer; - UInt8 *readPosition; - UInt8 *writePosition; - NSUInteger fillCount; - BOOL needsActivate; - NSInteger mode; - - NSUInteger internalSamplePosition; -} - -@property (readonly) UInt8 *buffer; -@property (readonly) UInt8 *readPosition; -@property (readonly) UInt8 *writePosition; -@property (readonly) NSUInteger fillCount; -@property (assign) BOOL needsActivate; -@property (assign) NSInteger mode; - -- (void) clear; -- (NSUInteger) fillCountRemaining; -- (BOOL) isFull; -- (BOOL) isEmpty; -- (UInt8) read; -- (void) write:(UInt8)theSample; -- (UInt8) generateInternalNoiseSample; -- (UInt8) generateWhiteNoiseSample; -- (void) fillWithNullSamples; -- (void) fillWithInternalNoise; -- (void) fillWithWhiteNoise; -+ (CocoaDSMic *) masterMic; -+ (void) setMasterMic:(CocoaDSMic *)theMic; - -@end diff --git a/desmume/src/cocoa/cocoa_mic.mm b/desmume/src/cocoa/cocoa_mic.mm deleted file mode 100644 index b8aaf6cc6..000000000 --- a/desmume/src/cocoa/cocoa_mic.mm +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (C) 2011 Roger Manuel - Copyright (C) 2012-2013 DeSmuME team - - This file is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the this software. If not, see . -*/ - -#import "cocoa_mic.h" -#import "cocoa_globals.h" - -#include "../NDSSystem.h" -#undef BOOL - -static CocoaDSMic *masterMic = nil; - -@implementation CocoaDSMic - -@synthesize buffer; -@synthesize readPosition; -@synthesize writePosition; -@synthesize fillCount; -@synthesize needsActivate; -@dynamic mode; - -- (id)init -{ - self = [super init]; - if (self == nil) - { - return self; - } - - UInt8 *newBuffer = (UInt8 *)malloc(MIC_BUFFER_SIZE); - if (newBuffer == nil) - { - [self release]; - return nil; - } - - buffer = newBuffer; - [self clear]; - - internalSamplePosition = 0; - needsActivate = YES; - mode = MICMODE_NONE; - - [CocoaDSMic setMasterMic:self]; - - return self; -} - -- (void)dealloc -{ - if ([CocoaDSMic masterMic] == self) - { - [CocoaDSMic setMasterMic:nil]; - } - - free(buffer); - buffer = NULL; - - [super dealloc]; -} - -- (NSInteger) mode -{ - return mode; -} - -- (void) setMode:(NSInteger)theMode -{ - switch (theMode) - { - case MICMODE_NONE: - self.needsActivate = YES; - break; - - case MICMODE_INTERNAL_NOISE: - self.needsActivate = YES; - break; - - case MICMODE_SOUND_FILE: - self.needsActivate = YES; - break; - - case MICMODE_WHITE_NOISE: - self.needsActivate = YES; - break; - - case MICMODE_PHYSICAL: - self.needsActivate = NO; - break; - - default: - break; - } - - mode = theMode; -} - -- (void) clear -{ - memset(buffer, MIC_NULL_SAMPLE_VALUE, MIC_BUFFER_SIZE); - readPosition = buffer; - writePosition = buffer; - fillCount = 0; -} - -- (NSUInteger) fillCountRemaining -{ - return (MIC_MAX_BUFFER_SAMPLES - self.fillCount); -} - -- (BOOL) isFull -{ - return (self.fillCount >= MIC_MAX_BUFFER_SAMPLES); -} - -- (BOOL) isEmpty -{ - return (self.fillCount == 0); -} - -- (UInt8) read -{ - UInt8 theSample = MIC_NULL_SAMPLE_VALUE; - - bool isMicActive = NDS_getFinalUserInput().mic.micButtonPressed; - if ([self isEmpty] || (self.needsActivate && !isMicActive)) - { - return theSample; - } - - theSample = *readPosition; - readPosition++; - fillCount--; - - // Move the pointer back to start if we reach the end of the memory block. - if (readPosition >= (buffer + MIC_BUFFER_SIZE)) - { - readPosition = buffer; - } - - return theSample; -} - -- (void) write:(UInt8)theSample -{ - if ([self isFull]) - { - return; - } - - *writePosition = theSample; - writePosition++; - fillCount++; - - // Move the pointer back to start if we reach the end of the memory block. - if (writePosition >= (buffer + MIC_BUFFER_SIZE)) - { - writePosition = buffer; - } -} - -- (UInt8) generateInternalNoiseSample -{ - internalSamplePosition++; - if (internalSamplePosition >= NUM_INTERNAL_NOISE_SAMPLES) - { - internalSamplePosition = 0; - } - - return noiseSample[internalSamplePosition]; -} - -- (UInt8) generateWhiteNoiseSample -{ - return (UInt8)(arc4random() & 0xFF); -} - -- (void) fillWithNullSamples -{ - while (self.fillCount < MIC_MAX_BUFFER_SAMPLES) - { - [self write:MIC_NULL_SAMPLE_VALUE]; - } -} - -- (void) fillWithInternalNoise -{ - while (self.fillCount < MIC_MAX_BUFFER_SAMPLES) - { - [self write:[self generateInternalNoiseSample]]; - } -} - -- (void) fillWithWhiteNoise -{ - while (self.fillCount < MIC_MAX_BUFFER_SAMPLES) - { - [self write:[self generateWhiteNoiseSample]]; - } -} - -+ (CocoaDSMic *) masterMic -{ - return masterMic; -} - -+ (void) setMasterMic:(CocoaDSMic *)theMic -{ - masterMic = theMic; -} - -@end - -BOOL Mic_Init() -{ - // Do nothing. The CocoaDSMic object will take care of this. - return TRUE; -} - -void Mic_Reset() -{ - // Do nothing. -} - -void Mic_DeInit() -{ - // Do nothing. The CocoaDSMic object will take care of this. -} - -u8 Mic_ReadSample() -{ - return [masterMic read]; -} - -void mic_savestate(EMUFILE* os) -{ - write32le(-1, os); -} - -bool mic_loadstate(EMUFILE* is, int size) -{ - is->fseek(size, SEEK_CUR); - return true; -} diff --git a/desmume/src/cocoa/coreaudiosound.cpp b/desmume/src/cocoa/coreaudiosound.cpp index c12a1cb7b..de27c402d 100644 --- a/desmume/src/cocoa/coreaudiosound.cpp +++ b/desmume/src/cocoa/coreaudiosound.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 DeSmuME team + Copyright (C) 2012-2013 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -175,11 +175,6 @@ CoreAudioOutput::~CoreAudioOutput() _spinlockAU = NULL; } -RingBuffer* CoreAudioOutput::getBuffer() const -{ - return this->_buffer; -} - void CoreAudioOutput::start() { this->clearBuffer(); @@ -199,9 +194,15 @@ void CoreAudioOutput::stop() this->clearBuffer(); } -void CoreAudioOutput::writeToBuffer(const void *buffer, size_t numberBytes) +void CoreAudioOutput::writeToBuffer(const void *buffer, size_t numberSampleFrames) { - this->getBuffer()->write(buffer, numberBytes); + size_t availableSampleFrames = this->_buffer->getAvailableElements(); + if (availableSampleFrames < numberSampleFrames) + { + this->_buffer->drop(numberSampleFrames - availableSampleFrames); + } + + this->_buffer->write(buffer, numberSampleFrames); } void CoreAudioOutput::clearBuffer() @@ -251,13 +252,12 @@ OSStatus CoreAudioOutputRenderCallback(void *inRefCon, { RingBuffer *__restrict__ audioBuffer = (RingBuffer *)inRefCon; UInt8 *__restrict__ playbackBuffer = (UInt8 *)ioData->mBuffers[0].mData; - const size_t totalReadSize = inNumberFrames * audioBuffer->getElementSize(); - const size_t bytesRead = audioBuffer->read(playbackBuffer, totalReadSize); + const size_t framesRead = audioBuffer->read(playbackBuffer, inNumberFrames); // Pad any remaining samples. - if (bytesRead < totalReadSize) + if (framesRead < inNumberFrames) { - memset(playbackBuffer + bytesRead, 0, totalReadSize - bytesRead); + memset(playbackBuffer + (framesRead * SPU_SAMPLE_SIZE), 0, (inNumberFrames - framesRead) * SPU_SAMPLE_SIZE); } // Copy to other channels. diff --git a/desmume/src/cocoa/coreaudiosound.h b/desmume/src/cocoa/coreaudiosound.h index 404610286..76ac58fb3 100644 --- a/desmume/src/cocoa/coreaudiosound.h +++ b/desmume/src/cocoa/coreaudiosound.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 DeSmuME team + Copyright (C) 2012-2013 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include #include "ringbuffer.h" + class CoreAudioOutput { private: @@ -38,10 +39,9 @@ public: void start(); void stop(); - void writeToBuffer(const void *buffer, size_t numberBytes); + void writeToBuffer(const void *buffer, size_t numberSampleFrames); void clearBuffer(); size_t getAvailableSamples() const; - RingBuffer* getBuffer() const; void mute(); void unmute(); float getVolume() const; diff --git a/desmume/src/cocoa/mic_ext.cpp b/desmume/src/cocoa/mic_ext.cpp new file mode 100644 index 000000000..c6a525b40 --- /dev/null +++ b/desmume/src/cocoa/mic_ext.cpp @@ -0,0 +1,102 @@ +/* + Copyright (C) 2011 Roger Manuel + Copyright (C) 2012-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#import "cocoa_globals.h" +#include "mic_ext.h" +#include "readwrite.h" + +RingBuffer micInputBuffer(MIC_MAX_BUFFER_SAMPLES * 2, sizeof(u8)); +NullGenerator nullSampleGenerator; +InternalNoiseGenerator internalNoiseGenerator; +WhiteNoiseGenerator whiteNoiseGenerator; +SineWaveGenerator sineWaveGenerator(250.0, MIC_SAMPLE_RATE); + +static bool _micUseBufferedSource = true; +static AudioGenerator *_selectedDirectSampleGenerator = NULL; + + +BOOL Mic_Init() +{ + // Do nothing. + return TRUE; +} + +void Mic_Reset() +{ + micInputBuffer.clear(); +} + +void Mic_DeInit() +{ + // Do nothing. +} + +u8 Mic_ReadSample() +{ + u8 theSample = MIC_NULL_SAMPLE_VALUE; + + if (_micUseBufferedSource) + { + if (micInputBuffer.isEmpty()) + { + return theSample; + } + + micInputBuffer.read(&theSample, 1); + } + else + { + if (_selectedDirectSampleGenerator != NULL) + { + theSample = _selectedDirectSampleGenerator->generateSample(); + } + } + + return theSample; +} + +bool Mic_GetUseBufferedSource() +{ + return _micUseBufferedSource; +} + +void Mic_SetUseBufferedSource(bool theState) +{ + _micUseBufferedSource = theState; +} + +AudioGenerator* Mic_GetSelectedDirectSampleGenerator() +{ + return _selectedDirectSampleGenerator; +} + +void Mic_SetSelectedDirectSampleGenerator(AudioGenerator *theGenerator) +{ + _selectedDirectSampleGenerator = theGenerator; +} + +void mic_savestate(EMUFILE* os) +{ + write32le(-1, os); +} + +bool mic_loadstate(EMUFILE* is, int size) +{ + is->fseek(size, SEEK_CUR); + return true; +} diff --git a/desmume/src/cocoa/mic_ext.h b/desmume/src/cocoa/mic_ext.h new file mode 100644 index 000000000..0a8b506a8 --- /dev/null +++ b/desmume/src/cocoa/mic_ext.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2011 Roger Manuel + Copyright (C) 2012-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#ifndef _MIC_EXTENSION_ +#define _MIC_EXTENSION_ + +#include "audiosamplegenerator.h" +#include "ringbuffer.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +bool Mic_GetUseBufferedSource(); +void Mic_SetUseBufferedSource(bool theState); +AudioGenerator* Mic_GetSelectedDirectSampleGenerator(); +void Mic_SetSelectedDirectSampleGenerator(AudioGenerator *theGenerator); + +extern RingBuffer micInputBuffer; +extern NullGenerator nullSampleGenerator; +extern InternalNoiseGenerator internalNoiseGenerator; +extern WhiteNoiseGenerator whiteNoiseGenerator; +extern SineWaveGenerator sineWaveGenerator; + +extern AudioGenerator *selectedGeneratorDirect; + +#ifdef __cplusplus +} +#endif + +#endif // _MIC_EXTENSION_ diff --git a/desmume/src/cocoa/openemu/NDSGameCore.h b/desmume/src/cocoa/openemu/NDSGameCore.h index f7134cc35..dfe85d25b 100644 --- a/desmume/src/cocoa/openemu/NDSGameCore.h +++ b/desmume/src/cocoa/openemu/NDSGameCore.h @@ -17,27 +17,29 @@ #import #import +#import "OENDSSystemResponderClient.h" #include @class CocoaDSFirmware; -@class CocoaDSMic; +@class CocoaDSController; @interface NDSGameCore : OEGameCore { - bool *input; - bool isTouchPressed; - OEIntPoint touchLocation; + NSPoint touchLocation; + CocoaDSController *cdsController; CocoaDSFirmware *firmware; - CocoaDSMic *microphone; + NSInteger micMode; NSInteger displayMode; OEIntRect displayRect; + NSInteger inputID[OENDSButtonCount]; // Key = OpenEmu's input ID, Value = DeSmuME's input ID OSSpinLock spinlockDisplayMode; } +@property (retain) CocoaDSController *cdsController; @property (retain) CocoaDSFirmware *firmware; -@property (retain) CocoaDSMic *microphone; +@property (assign) NSInteger micMode; @property (assign) NSInteger displayMode; @end diff --git a/desmume/src/cocoa/openemu/NDSGameCore.mm b/desmume/src/cocoa/openemu/NDSGameCore.mm index a31ad8156..6aea7fc04 100644 --- a/desmume/src/cocoa/openemu/NDSGameCore.mm +++ b/desmume/src/cocoa/openemu/NDSGameCore.mm @@ -19,8 +19,8 @@ #import "cocoa_globals.h" #import "cocoa_file.h" #import "cocoa_firmware.h" +#import "cocoa_input.h" #import "cocoa_core.h" -#import "cocoa_mic.h" #import "cocoa_output.h" #import "OESoundInterface.h" #import "OENDSSystemResponderClient.h" @@ -32,8 +32,9 @@ @implementation NDSGameCore +@synthesize cdsController; @synthesize firmware; -@synthesize microphone; +@synthesize micMode; @dynamic displayMode; - (id)init @@ -45,20 +46,37 @@ } // Set up input handling - input = (bool *)calloc(sizeof(bool), OENDSButtonCount); - isTouchPressed = false; touchLocation.x = 0; touchLocation.y = 0; - microphone = [[CocoaDSMic alloc] init]; - microphone.mode = MICMODE_INTERNAL_NOISE; + micMode = MICMODE_INTERNAL_NOISE; + + inputID[OENDSButtonUp] = DSControllerState_Up; + inputID[OENDSButtonDown] = DSControllerState_Down; + inputID[OENDSButtonLeft] = DSControllerState_Left; + inputID[OENDSButtonRight] = DSControllerState_Right; + inputID[OENDSButtonA] = DSControllerState_A; + inputID[OENDSButtonB] = DSControllerState_B; + inputID[OENDSButtonX] = DSControllerState_X; + inputID[OENDSButtonY] = DSControllerState_Y; + inputID[OENDSButtonL] = DSControllerState_L; + inputID[OENDSButtonR] = DSControllerState_R; + inputID[OENDSButtonStart] = DSControllerState_Start; + inputID[OENDSButtonSelect] = DSControllerState_Select; + inputID[OENDSButtonMicrophone] = DSControllerState_Microphone; + inputID[OENDSButtonLid] = DSControllerState_Lid; + inputID[OENDSButtonDebug] = DSControllerState_Debug; // Set up the emulation core CommonSettings.advanced_timing = true; CommonSettings.use_jit = false; [CocoaDSCore startupCore]; + // Set up the DS controller + cdsController = [[[[CocoaDSController alloc] init] retain] autorelease]; + [cdsController setMicMode:MICMODE_INTERNAL_NOISE]; + // Set up the DS firmware using the internal firmware - firmware = [[CocoaDSFirmware alloc] init]; + firmware = [[[[CocoaDSFirmware alloc] init] retain] autorelease]; [firmware update]; // Set up the 3D renderer @@ -103,14 +121,12 @@ - (void)dealloc { - self.microphone = nil; - free(input); - SPU_ChangeSoundCore(SNDCORE_DUMMY, 0); NDS_3D_ChangeCore(CORE3DLIST_NULL); [CocoaDSCore shutdownCore]; - self.firmware = nil; + [self setCdsController:nil]; + [self setFirmware:nil]; [super dealloc]; } @@ -175,7 +191,7 @@ - (void)executeFrame { - [self updateNDSController]; + [cdsController flush]; NDS_beginProcessingInput(); NDS_endProcessingInput(); @@ -282,36 +298,35 @@ return [self audioSampleRate]; } - #pragma mark Input - (oneway void)didPushNDSButton:(OENDSButton)button forPlayer:(NSUInteger)player { - input[button] = true; + [cdsController setControllerState:YES controlID:inputID[button]]; } - (oneway void)didReleaseNDSButton:(OENDSButton)button forPlayer:(NSUInteger)player { - input[button] = false; + [cdsController setControllerState:NO controlID:inputID[button]]; } - (oneway void)didTouchScreenPoint:(OEIntPoint)aPoint { - bool touchPressed = false; + BOOL isTouchPressed = NO; NSInteger dispMode = [self displayMode]; switch (dispMode) { case DS_DISPLAY_TYPE_MAIN: - touchPressed = false; // Reject touch input if showing only the main screen. + isTouchPressed = NO; // Reject touch input if showing only the main screen. break; case DS_DISPLAY_TYPE_TOUCH: - touchPressed = true; + isTouchPressed = YES; break; case DS_DISPLAY_TYPE_COMBO: - touchPressed = true; + isTouchPressed = YES; aPoint.y -= GPU_DISPLAY_HEIGHT; // Normalize the y-coordinate to the DS. break; @@ -339,65 +354,13 @@ aPoint.y = (GPU_DISPLAY_HEIGHT - 1); } - isTouchPressed = touchPressed; - touchLocation = aPoint; + touchLocation = NSMakePoint(aPoint.x, aPoint.y); + [cdsController setTouchState:isTouchPressed location:touchLocation]; } - (oneway void)didReleaseTouch { - isTouchPressed = false; -} - -- (void) updateNDSController -{ - // Setup the DS pad. - NDS_setPad(input[OENDSButtonRight], - input[OENDSButtonLeft], - input[OENDSButtonDown], - input[OENDSButtonUp], - input[OENDSButtonSelect], - input[OENDSButtonStart], - input[OENDSButtonB], - input[OENDSButtonA], - input[OENDSButtonY], - input[OENDSButtonX], - input[OENDSButtonL], - input[OENDSButtonR], - input[OENDSButtonDebug], - input[OENDSButtonLid]); - - // Setup the DS touch pad. - if (isTouchPressed) - { - NDS_setTouchPos((u16)touchLocation.x, (u16)touchLocation.y); - } - else - { - NDS_releaseTouch(); - } - - // Setup the DS mic. - NDS_setMic(input[OENDSButtonMicrophone]); - - if (input[OENDSButtonMicrophone]) - { - if (self.microphone.mode == MICMODE_NONE) - { - [self.microphone fillWithNullSamples]; - } - else if (self.microphone.mode == MICMODE_INTERNAL_NOISE) - { - [self.microphone fillWithInternalNoise]; - } - else if (self.microphone.mode == MICMODE_WHITE_NOISE) - { - [self.microphone fillWithWhiteNoise]; - } - else if (self.microphone.mode == MICMODE_SOUND_FILE) - { - // TODO: Need to implement. Does nothing for now. - } - } + [cdsController setTouchState:NO location:touchLocation]; } - (NSTrackingAreaOptions)mouseTrackingOptions diff --git a/desmume/src/cocoa/ringbuffer.cpp b/desmume/src/cocoa/ringbuffer.cpp index 8123fa1e8..5ed2ca39f 100644 --- a/desmume/src/cocoa/ringbuffer.cpp +++ b/desmume/src/cocoa/ringbuffer.cpp @@ -23,14 +23,15 @@ RingBuffer::RingBuffer(const size_t numberElements, const size_t newBufferElementSize) { - _buffer = (uint8_t *)calloc(numberElements + 1, newBufferElementSize); - _bufferSize = (numberElements + 1) * newBufferElementSize; - _numElements = numberElements; + _elementCapacity = numberElements; _elementSize = newBufferElementSize; - _readPosition = newBufferElementSize - 1; - _writePosition = newBufferElementSize; - _bufferFillSize = 0; + _buffer = (uint8_t *)calloc(numberElements + 2, newBufferElementSize); + _bufferSize = (numberElements + 2) * newBufferElementSize; + + _readPosition = 0; + _writePosition = 1; + _elementFillCount = 0; } RingBuffer::~RingBuffer() @@ -41,58 +42,66 @@ RingBuffer::~RingBuffer() void RingBuffer::clear() { - this->_readPosition = this->_elementSize - 1; - this->_writePosition = this->_elementSize; - this->_bufferFillSize = 0; + this->_readPosition = 0; + this->_writePosition = 1; + this->_elementFillCount = 0; memset(_buffer, 0, this->_bufferSize); } -size_t RingBuffer::read(void *__restrict__ destBuffer, size_t requestedNumberBytes) +size_t RingBuffer::read(void *__restrict__ destBuffer, size_t requestedNumberElements) { if (destBuffer == NULL) { return 0; } - size_t hiBufferAvailable = 0; - size_t loBufferAvailable = 0; + size_t hiElementsAvailable = 0; + size_t loElementsAvailable = 0; const uint8_t *__restrict__ inputData = this->_buffer; size_t inputDataReadPos = this->_readPosition; const size_t inputDataWritePos = this->_writePosition; - const size_t inputDataSize = this->_bufferSize; + const size_t inputDataSize = this->_elementCapacity + 2; // Check buffer availability if (inputDataReadPos < inputDataWritePos) { - hiBufferAvailable = inputDataWritePos - inputDataReadPos - 1; + hiElementsAvailable = inputDataWritePos - inputDataReadPos - 1; } else if (inputDataReadPos > inputDataWritePos) { - hiBufferAvailable = inputDataSize - inputDataReadPos - 1; - loBufferAvailable = inputDataWritePos; - } - - // Bounds check for buffer overrun - if (requestedNumberBytes > hiBufferAvailable + loBufferAvailable) - { - requestedNumberBytes = hiBufferAvailable + loBufferAvailable; - requestedNumberBytes -= requestedNumberBytes % this->_elementSize; - } - - // Copy ring buffer to destination buffer - if (requestedNumberBytes <= hiBufferAvailable) - { - memcpy(destBuffer, inputData + inputDataReadPos + 1, requestedNumberBytes); + hiElementsAvailable = inputDataSize - inputDataReadPos - 1; + loElementsAvailable = inputDataWritePos; } else { - memcpy(destBuffer, inputData + inputDataReadPos + 1, hiBufferAvailable); - memcpy((uint8_t *)destBuffer + hiBufferAvailable, inputData, requestedNumberBytes - hiBufferAvailable); + return requestedNumberElements; + } + + // Bounds check for buffer overrun + if (requestedNumberElements > hiElementsAvailable + loElementsAvailable) + { + requestedNumberElements = hiElementsAvailable + loElementsAvailable; + } + + if (requestedNumberElements == 0) + { + return requestedNumberElements; + } + + // Copy ring buffer to destination buffer + if (requestedNumberElements <= hiElementsAvailable) + { + memcpy(destBuffer, inputData + ((inputDataReadPos + 1) * this->_elementSize), requestedNumberElements * this->_elementSize); + } + else + { + memcpy(destBuffer, inputData + ((inputDataReadPos + 1) * this->_elementSize), hiElementsAvailable * this->_elementSize); + memcpy((uint8_t *)destBuffer + (hiElementsAvailable * this->_elementSize), inputData, (requestedNumberElements - hiElementsAvailable) * this->_elementSize); } // Advance the read position - inputDataReadPos += requestedNumberBytes; + inputDataReadPos += requestedNumberElements; if (inputDataReadPos >= inputDataSize) { inputDataReadPos -= inputDataSize; @@ -101,92 +110,149 @@ size_t RingBuffer::read(void *__restrict__ destBuffer, size_t requestedNumberByt this->_readPosition = inputDataReadPos; // Decrease the fill size now that we're done reading. - OSAtomicAdd32Barrier(-(int32_t)requestedNumberBytes, &this->_bufferFillSize); + OSAtomicAdd32Barrier(-(int32_t)requestedNumberElements, &this->_elementFillCount); - return requestedNumberBytes; + return requestedNumberElements; } -size_t RingBuffer::write(const void *__restrict__ srcBuffer, size_t requestedNumberBytes) +size_t RingBuffer::write(const void *__restrict__ srcBuffer, size_t requestedNumberElements) { if (srcBuffer == NULL) { return 0; } - size_t hiBufferAvailable = 0; - size_t loBufferAvailable = 0; + size_t hiElementsAvailable = 0; + size_t loElementsAvailable = 0; uint8_t *__restrict__ inputData = this->_buffer; const size_t inputDataReadPos = this->_readPosition; size_t inputDataWritePos = this->_writePosition; - const size_t inputDataSize = this->_bufferSize; + const size_t inputDataSize = this->_elementCapacity + 2; // Check buffer availability. - if (inputDataWritePos >= inputDataReadPos) + if (inputDataWritePos > inputDataReadPos) { - hiBufferAvailable = inputDataSize - inputDataWritePos; - loBufferAvailable = inputDataReadPos; - - // Subtract one element's worth of bytes - if (loBufferAvailable > 0) - { - loBufferAvailable -= 1; - } - else - { - hiBufferAvailable -= 1; - } + hiElementsAvailable = inputDataSize - inputDataWritePos; + loElementsAvailable = (inputDataReadPos > 0) ? inputDataReadPos - 1 : 0; } - else // (inputDataWritePos < inputDataReadPos) + else if (inputDataWritePos < inputDataReadPos) { - hiBufferAvailable = inputDataReadPos - inputDataWritePos - 1; - } - - // Bounds check for buffer overrun - if (requestedNumberBytes > hiBufferAvailable + loBufferAvailable) - { - requestedNumberBytes = hiBufferAvailable + loBufferAvailable; - requestedNumberBytes -= requestedNumberBytes % this->_elementSize; - } - - // Increase the fill size before writing anything. - OSAtomicAdd32Barrier((int32_t)requestedNumberBytes, &this->_bufferFillSize); - - // Copy source buffer to ring buffer. - if (requestedNumberBytes <= hiBufferAvailable) - { - memcpy(inputData + inputDataWritePos, srcBuffer, requestedNumberBytes); + hiElementsAvailable = inputDataReadPos - inputDataWritePos - 1; } else { - memcpy(inputData + inputDataWritePos, srcBuffer, hiBufferAvailable); - memcpy(inputData, (uint8_t *)srcBuffer + hiBufferAvailable, requestedNumberBytes - hiBufferAvailable); - + return requestedNumberElements; + } + + // Bounds check for buffer overrun + if (requestedNumberElements > hiElementsAvailable + loElementsAvailable) + { + requestedNumberElements = hiElementsAvailable + loElementsAvailable; + } + + if (requestedNumberElements == 0) + { + return requestedNumberElements; + } + + // Increase the fill size before writing anything. + OSAtomicAdd32Barrier((int32_t)requestedNumberElements, &this->_elementFillCount); + + // Copy source buffer to ring buffer. + if (requestedNumberElements <= hiElementsAvailable) + { + memcpy(inputData + (inputDataWritePos * this->_elementSize), srcBuffer, requestedNumberElements * this->_elementSize); + } + else + { + memcpy(inputData + (inputDataWritePos * this->_elementSize), srcBuffer, hiElementsAvailable * this->_elementSize); + memcpy(inputData, (uint8_t *)srcBuffer + (hiElementsAvailable * this->_elementSize), (requestedNumberElements - hiElementsAvailable) * this->_elementSize); } // Advance the write position. - inputDataWritePos += requestedNumberBytes; - if (inputDataWritePos >= inputDataSize) + inputDataWritePos += requestedNumberElements; + if (inputDataWritePos > inputDataSize) { inputDataWritePos -= inputDataSize; } this->_writePosition = inputDataWritePos; - - return requestedNumberBytes; + + return requestedNumberElements; } -size_t RingBuffer::getBufferFillSize() const +size_t RingBuffer::drop(size_t requestedNumberElements) { - return (size_t)this->_bufferFillSize; + size_t hiElementsAvailable = 0; + size_t loElementsAvailable = 0; + + size_t inputDataReadPos = this->_readPosition; + const size_t inputDataWritePos = this->_writePosition; + const size_t inputDataSize = this->_elementCapacity + 2; + + // Check buffer availability + if (inputDataReadPos < inputDataWritePos) + { + hiElementsAvailable = inputDataWritePos - inputDataReadPos - 1; + } + else if (inputDataReadPos > inputDataWritePos) + { + hiElementsAvailable = inputDataSize - inputDataReadPos - 1; + loElementsAvailable = inputDataWritePos; + } + else + { + return requestedNumberElements; + } + + // Bounds check for buffer overrun + if (requestedNumberElements > hiElementsAvailable + loElementsAvailable) + { + requestedNumberElements = hiElementsAvailable + loElementsAvailable; + } + + if (requestedNumberElements == 0) + { + return requestedNumberElements; + } + + // Advance the read position + inputDataReadPos += requestedNumberElements; + if (inputDataReadPos >= inputDataSize) + { + inputDataReadPos -= inputDataSize; + } + + this->_readPosition = inputDataReadPos; + + // Decrease the fill size now that we're done reading. + OSAtomicAdd32Barrier(-(int32_t)requestedNumberElements, &this->_elementFillCount); + + return requestedNumberElements; } size_t RingBuffer::getAvailableElements() const { - return ((this->_bufferSize - this->_bufferFillSize) / this->_elementSize) - 1; + return (this->_elementCapacity - this->_elementFillCount); +} + +size_t RingBuffer::getElementCapacity() const +{ + return this->_elementCapacity; } size_t RingBuffer::getElementSize() const { return this->_elementSize; } + +bool RingBuffer::isEmpty() const +{ + return (this->_elementFillCount == 0); +} + +bool RingBuffer::isFull() const +{ + return ((size_t)this->_elementFillCount >= this->_elementCapacity); +} diff --git a/desmume/src/cocoa/ringbuffer.h b/desmume/src/cocoa/ringbuffer.h index 50a4061fc..71c725c03 100644 --- a/desmume/src/cocoa/ringbuffer.h +++ b/desmume/src/cocoa/ringbuffer.h @@ -26,11 +26,11 @@ class RingBuffer { private: uint8_t *_buffer; - uint8_t *_bufferEnd; size_t _bufferSize; - size_t _numElements; + + size_t _elementCapacity; size_t _elementSize; - int32_t _bufferFillSize; // need to use int32_t for OSAtomicAdd32Barrier() + int32_t _elementFillCount; // need to use int32_t for OSAtomicAdd32Barrier() size_t _readPosition; size_t _writePosition; @@ -39,11 +39,14 @@ public: ~RingBuffer(); void clear(); - size_t read(void *__restrict__ destBuffer, size_t requestedNumberBytes); - size_t write(const void *__restrict__ srcBuffer, size_t requestedNumberBytes); - size_t getBufferFillSize() const; + size_t read(void *__restrict__ destBuffer, size_t requestedNumberElements); + size_t write(const void *__restrict__ srcBuffer, size_t requestedNumberElements); + size_t drop(size_t requestedNumberElements); size_t getAvailableElements() const; + size_t getElementCapacity() const; size_t getElementSize() const; + bool isEmpty() const; + bool isFull() const; }; #endif diff --git a/desmume/src/cocoa/sndOSX.cpp b/desmume/src/cocoa/sndOSX.cpp index 78e140126..bb478713f 100644 --- a/desmume/src/cocoa/sndOSX.cpp +++ b/desmume/src/cocoa/sndOSX.cpp @@ -93,7 +93,7 @@ void SNDOSXUpdateAudio(s16 *buffer, u32 num_samples) return; } - coreAudioPlaybackManager->writeToBuffer(buffer, coreAudioPlaybackManager->getBuffer()->getElementSize() * (size_t)num_samples); + coreAudioPlaybackManager->writeToBuffer(buffer, num_samples); } u32 SNDOSXGetAudioSpace() diff --git a/desmume/src/cocoa/translations/English.lproj/MainMenu.strings b/desmume/src/cocoa/translations/English.lproj/MainMenu.strings index e01d9151e19ee3c9d105c0c28b8b5a2d4c1e3ef5..b57f41bae9ab85e9e9e9d9db1dc68ea196da57b3 100644 GIT binary patch delta 1118 zcmdT@%}-N75Z~RY6`KZMq)}2ne10Grn)+(AHFz;0e#8(zg38erS^+Hu+N#6@u?c~b zMzfLeM8I&+Q2LdI0w#zYh#{I(6Av0iIB-}00%u=E5)U3tJnZhtRtGABQ?@ehvmcs1){^zrtlU zatMtSJlPhbj3LT#6B8NujtgnfM<(GYuK0u%of+_NA_|1K&v7*gZZsZ?9azjlErxT@ zh`o=51NAsRfMcUz!S_?}5a)A{lsnV4CDTe8yx5$FBrYv-LmDm}8>hjEkpbcSji{FW zbq-|@OWP4Ue$GKzpqJeul8SPSb(xfPc83bSZQ2xdC4-y%O=OMG*=BkIEXZz9Y>eay z(YMa7E1AqwPEL#;tB1zLTWs42o5M5A=?rihXt0iqft@p|y^ z3^d4`%TcAXb`#QVLX@2&BeG{+;e9S97)(Umv+A;3=6D1Q%EtJ>Bb$s=K*AvbsFRd%Q53@g@3jJ-|A~PS$ RG@YHN{-_b!%T6#G`w8+?D?$JO delta 1469 zcmd5+T}V@582--p9+ybboD0pB9ShOY=9KV1g&1@Z z;-Ov;G$AiU*EVEkf>2rn#Sp#dA}>U+%LtP$q6m7=&LYW+f}rBS;r)5O_xJg}zES=B zgx=RH^ztz1$CPD%f*@hr5bRduTmvpCW=#+t`RD5p`;(x-P zRMroRiS5kIoXpN7R>wM6C-dOVA;`prF|a6$CNXJ?pV@HEC6p=+Pf}1{!gaeOc9l-M zSu5*iUglsn(w#ULgye$~h4hfKgURH!Z;`#xlrGkUUsqu7Q5&f)`s@@#rhgM1mB}Vi z2ME&>0wY@Pas&4H zAq_8Zo`W^_APaK>Fn&ebP&bX9SU`MGx7QfuS0`z9)=V68lFdPq#+(*Hwnq`_=GCox z$)j!j`~JPeFFWDdFc^efTn>PQi<4AL-z^~(%|Y=0jl@%GPBR_~QDT1xtWo~&)VlaV z<>OP3jn9K%+@^L(z2J^8B%^#=FlKj=#To5iokOmn7lJHI# zwo`^b;`(ej#`S+x>hJS9PGYB+1M^<;42`Y+N1GW9$ ziDJD{Gn1g`-^GaRehkgH8WIZd*c!wuM+)~xqbeK42K8kWg<@Pv5lmRJ1_>BW;aQ6B zhE=iXMD&QFQOH-WT{oe$Arzs$ibm)jg7~;{+KmHCzrX=(l(`W{UeIeITZx5qCFtT2 WMkvSoA9=PK4A*BtH*KB)!})K|;)nkL diff --git a/desmume/src/cocoa/translations/English.lproj/MainMenu.xib b/desmume/src/cocoa/translations/English.lproj/MainMenu.xib index c120a35fe..aee6b5e65 100644 --- a/desmume/src/cocoa/translations/English.lproj/MainMenu.xib +++ b/desmume/src/cocoa/translations/English.lproj/MainMenu.xib @@ -12,9 +12,8 @@ YES - - + YES @@ -7046,7 +7045,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {1.79769e+308, 1.79769e+308} {620, 180} - + 256 YES @@ -7391,7 +7390,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {620, 442} - {{0, 0}, {1920, 1178}} {620, 202} @@ -7405,8 +7403,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA Input Profile Rename NSWindow + {1.79769e+308, 1.79769e+308} - + 256 YES @@ -7466,7 +7465,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {452, 115} - {{0, 0}, {1920, 1178}} {1.79769e+308, 1.79769e+308} @@ -7474,165 +7472,17 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 1 2 - {{235, 183}, {600, 376}} + {{235, 292}, {620, 267}} 1685586944 InputSettingsMicrophone NSWindow {1.79769e+308, 1.79769e+308} - + 256 YES - - - 12 - - YES - - - 274 - - YES - - - 268 - {{18, 69}, {528, 18}} - - YES - - 537001472 - 0 - - 50 - 38 - 47 - 2 - - - - - 268 - {{16, 39}, {532, 25}} - - YES - - -1543373312 - 0 - - - 100 - 0.0 - 50 - 0.0 - 5 - 0 - NO - NO - - - - - 268 - {{247, 14}, {70, 17}} - - YES - - 605158976 - 272630784 - Input Gain - - - - - - - - - 268 - {{15, 109}, {54, 17}} - - YES - - 605158976 - 272630784 - Device: - - - - - - - - - 268 - {{71, 103}, {478, 26}} - - YES - - -1539178944 - 2048 - - - 109199615 - 129 - - - 400 - 75 - - - - - 1048576 - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - - 1 - YES - YES - 2 - - - - {{1, 1}, {564, 137}} - - - - {{17, 56}, {566, 153}} - - {0, 0} - - 67239424 - 0 - Sound Input Device Settings - - - - 3 - MCAwLjgwMDAwMDAxMTkAA - - - - 1 - 0 - 2 - NO - 12 @@ -7646,7 +7496,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{18, 14}, {290, 78}} + {{18, 14}, {190, 126}} YES 4 @@ -7654,12 +7504,12 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES - 604110336 + -2080244224 0 - Sound Input Device (NOT IMPLEMENTED) + Internal Noise Samples - 4 + 1 1211912703 0 @@ -7669,12 +7519,12 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 25 - -2080244224 + 67239424 0 - Internal Noise Samples + White Noise - 1 + 3 1211912703 0 @@ -7777,10 +7627,10 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 67239424 0 - White Noise + Sine Wave - 3 + 5 1211912703 0 @@ -7788,9 +7638,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 75 - 604110336 + 67239424 0 - Sound File: + Audio File 2 @@ -7801,7 +7651,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 75 - {290, 18} + {190, 30} {4, 2} 1151868928 NSActionCell @@ -7857,8 +7707,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 400 75 - 1 - + @@ -7866,7 +7715,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{130, 12}, {324, 21}} + {{130, 18}, {224, 21}} YES @@ -7874,7 +7723,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 272635904 - NOT IMPLEMENTED + File Name YES @@ -7884,11 +7733,11 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{456, 5}, {96, 32}} + {{476, 11}, {96, 32}} YES - 604110336 + 67239424 134217728 Choose... @@ -7901,18 +7750,135 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 25 + + + 268 + {{128, 47}, {348, 26}} + + YES + + -2079981824 + 0 + + + 5000 + 100 + 500 + 0.0 + 11 + 1 + NO + NO + + + + + 268 + {{479, 56}, {90, 17}} + + YES + + 68288064 + 71308288 + + + + YES + + YES + allowsFloats + alwaysShowsDecimalSeparator + formatterBehavior + generatesDecimalNumbers + locale + maximumFractionDigits + negativeInfinitySymbol + nilSymbol + numberStyle + positiveFormat + positiveInfinitySymbol + usesGroupingSeparator + + + YES + + + + + + + -∞ + + + #0.0 Hz + +∞ + + + + #0.0 Hz + #0.0 Hz + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + . + , + NO + NO + YES + + %1.1f Hz + + + + + + + + 268 + {{356, 11}, {124, 32}} + + YES + + 67239424 + 134217728 + Choose None + + + -2038284033 + 129 + + + 200 + 25 + + - {{1, 1}, {564, 102}} + {{1, 1}, {584, 150}} - {{17, 213}, {566, 118}} + {{17, 56}, {586, 166}} {0, 0} 67239424 0 - Sample Source + Audio Sample Generators @@ -7929,7 +7895,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{490, 12}, {96, 32}} + {{510, 12}, {96, 32}} 1 YES @@ -7950,7 +7916,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{394, 12}, {96, 32}} + {{414, 12}, {96, 32}} YES @@ -7970,7 +7936,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{17, 339}, {566, 17}} + {{17, 230}, {566, 17}} YES @@ -7985,7 +7951,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - {600, 376} + {620, 267} + {{0, 0}, {1920, 1178}} {1.79769e+308, 1.79769e+308} @@ -11321,7 +11288,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA CheatWindowDelegate - + 256 YES @@ -11330,7 +11297,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 292 {{17, 4}, {294, 14}} - YES 68288064 @@ -11348,7 +11314,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{214, 220}, {16, 16}} - 28938 100 @@ -11357,7 +11322,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{133, 369}, {136, 22}} - YES -1539178944 @@ -11414,7 +11378,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{59, 374}, {60, 14}} - YES 68288064 @@ -11431,7 +11394,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{59, 398}, {72, 14}} - YES 68288064 @@ -11448,7 +11410,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{133, 393}, {136, 22}} - YES -2076049856 @@ -11505,7 +11466,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{0, 237}, {328, 134}} - NSView @@ -11513,7 +11473,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{233, 213}, {80, 28}} - YES 67239424 @@ -11534,7 +11493,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{59, 222}, {150, 14}} - YES 68288064 @@ -11552,7 +11510,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 222}, {45, 14}} - YES 68288064 @@ -11579,14 +11536,12 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 256 {286, 176} - YES 256 {286, 17} - @@ -11594,7 +11549,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2147483392 {{224, 0}, {16, 17}} - YES @@ -11674,7 +11628,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 17}, {286, 176}} - @@ -11685,7 +11638,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2147483392 {{224, 17}, {15, 102}} - _doScroller: 0.94863013698630139 @@ -11695,7 +11647,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2147483392 {{1, 294}, {338, 15}} - 1 _doScroller: @@ -11710,7 +11661,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 0}, {286, 17}} - @@ -11720,7 +11670,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{20, 20}, {288, 194}} - 562 @@ -11732,8 +11681,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {328, 434} - - NSView @@ -11758,7 +11705,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {1.79769e+308, 1.79769e+308} {500, 272} - + 256 YES @@ -11777,14 +11724,12 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 256 {500, 287} - YES 256 {500, 17} - @@ -11792,7 +11737,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2147483392 {{224, 0}, {16, 17}} - YES @@ -11874,7 +11818,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 17}, {500, 287}} - @@ -11885,7 +11828,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2147483392 {{224, 17}, {15, 102}} - _doScroller: 0.94773519163763065 @@ -11895,7 +11837,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2147483392 {{1, 249}, {568, 15}} - 1 _doScroller: @@ -11910,7 +11851,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 0}, {500, 17}} - @@ -11920,7 +11860,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{-1, 57}, {502, 305}} - 562 @@ -11935,7 +11874,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 370}, {120, 14}} - YES 68288064 @@ -11952,7 +11890,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 392}, {63, 14}} - YES 68288064 @@ -11969,7 +11906,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 292 {{14, 12}, {114, 32}} - YES 67239424 @@ -11990,7 +11926,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 292 {{128, 12}, {114, 32}} - YES 67239424 @@ -12011,7 +11946,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 289 {{390, 12}, {96, 32}} - 1 YES @@ -12033,7 +11967,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 289 {{294, 12}, {96, 32}} - YES 67239424 @@ -12054,7 +11987,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 265 {{378, 370}, {42, 14}} - YES 68288064 @@ -12071,7 +12003,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{139, 370}, {237, 14}} - YES 68288064 @@ -12089,7 +12020,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 265 {{422, 370}, {61, 14}} - YES 68288064 @@ -12107,7 +12037,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{82, 392}, {401, 14}} - YES 68288064 @@ -12122,15 +12051,13 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {500, 416} - - {{0, 0}, {1920, 1178}} {500, 294} {1.79769e+308, 1.79769e+308} - + 268 YES @@ -12139,7 +12066,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{233, 54}, {80, 28}} - YES 67239424 @@ -12160,7 +12086,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{20, 59}, {210, 19}} - YES 343014976 @@ -12222,7 +12147,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 86}, {294, 14}} - YES 67239424 @@ -12239,7 +12163,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 100}, {294, 14}} - YES 67239424 @@ -12253,8 +12176,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {328, 134} - - NSView @@ -12443,7 +12364,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA NSView - + 301 YES @@ -12452,7 +12373,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{197, 191}, {109, 32}} - YES 67239424 @@ -12473,7 +12393,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 20}, {286, 42}} - YES 67239424 @@ -12490,7 +12409,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 262}, {128, 17}} - YES 68288064 @@ -12507,7 +12425,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 265 {{149, 257}, {27, 27}} - YES -2080244224 @@ -12529,7 +12446,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{79, 230}, {38, 17}} - YES 68288064 @@ -12550,7 +12466,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{67, 198}, {128, 22}} - YES -1804468671 @@ -12622,7 +12537,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 201}, {45, 17}} - YES 68288064 @@ -12639,7 +12553,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{122, 228}, {73, 22}} - YES -1804468671 @@ -12657,7 +12570,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{17, 231}, {60, 17}} - YES 68288064 @@ -12684,7 +12596,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{18, 14}, {190, 78}} - YES 4 1 @@ -12903,12 +12814,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {226, 102}} - {{46, 72}, {228, 118}} - {0, 0} 67239424 @@ -12929,8 +12838,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {320, 290} - - NSView @@ -15198,7 +15105,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {1.79769e+308, 1.79769e+308} - + 256 YES @@ -15217,7 +15124,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 77}, {206, 18}} - YES -2080244224 @@ -15240,7 +15146,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 57}, {134, 18}} - YES -2080244224 @@ -15263,7 +15168,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 37}, {80, 18}} - YES -2080244224 @@ -15286,7 +15190,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{185, 12}, {45, 19}} - YES -1804468671 @@ -15367,7 +15270,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 14}, {165, 14}} - YES 68288064 @@ -15382,12 +15284,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 103}} - {{17, 241}, {250, 119}} - {0, 0} 67239424 @@ -15411,7 +15311,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{65, 18}, {154, 19}} - YES -2080244224 @@ -15442,7 +15341,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{18, 14}, {107, 58}} - YES 3 1 @@ -15647,12 +15545,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 82}} - {{17, 442}, {250, 98}} - {0, 0} 67239424 @@ -15686,7 +15582,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{18, 14}, {120, 98}} - YES 5 1 @@ -15951,12 +15846,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 122}} - {{17, 41}, {250, 138}} - {0, 0} 67239424 @@ -15990,7 +15883,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 32}, {113, 18}} - YES -2080244224 @@ -16013,7 +15905,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 12}, {108, 18}} - YES -2080244224 @@ -16034,12 +15925,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 58}} - {{17, 364}, {250, 74}} - {0, 0} 67239424 @@ -16073,7 +15962,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{16, 12}, {192, 18}} - YES 67239424 @@ -16094,12 +15982,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 38}} - {{17, 183}, {250, 54}} - {0, 0} 67239424 @@ -16120,8 +16006,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {284, 560} - - {{0, 0}, {1920, 1178}} {1.79769e+308, 1.79769e+308} @@ -29295,6 +29179,70 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 7754 + + + value: selection.object1 + + + + + + value: selection.object1 + value + selection.object1 + 2 + + + 7755 + + + + value: selection.floatValue0 + + + + + + value: selection.floatValue0 + value + selection.floatValue0 + 2 + + + 7763 + + + + value: selection.floatValue0 + + + + + + value: selection.floatValue0 + value + selection.floatValue0 + 2 + + + 7764 + + + + audioFileChoose: + + + + 7769 + + + + audioFileChooseNone: + + + + 7770 + @@ -38486,10 +38434,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES - + - @@ -38514,19 +38461,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - - 7181 - - - YES - - - - - - - - 7182 @@ -38534,7 +38468,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES + + + @@ -38589,11 +38526,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - - 7190 - - - 7191 @@ -38604,94 +38536,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - - 7193 - - - YES - - - - - - 7194 - - - YES - - - - - - 7195 - - - YES - - - - - - 7196 - - - YES - - - - - - 7197 - - - YES - - - - - - 7198 - - - - - 7199 - - - YES - - - - - - 7200 - - - YES - - - - - - 7201 - - - - - 7202 - - - - - 7203 - - - - - 7204 - - - 7210 @@ -40082,6 +39926,62 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + + 7190 + + + + + 7759 + + + YES + + + + + + 7760 + + + + + 7761 + + + YES + + + + + + 7762 + + + YES + + + + + + 7765 + + + + + 7766 + + + YES + + + + + + 7767 + + + @@ -41779,8 +41679,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 7179.IBWindowTemplateEditedContentRect 7179.NSWindowTemplate.visibleAtLaunch 7180.IBPluginDependency - 7181.IBPluginDependency - 7181.IBViewBoundsToFrameTransform 7182.IBPluginDependency 7182.IBViewBoundsToFrameTransform 7183.IBPluginDependency @@ -41798,26 +41696,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 7190.IBAttributePlaceholdersKey 7191.IBPluginDependency 7192.IBPluginDependency - 7193.IBPluginDependency - 7193.IBViewBoundsToFrameTransform - 7194.IBPluginDependency - 7194.IBViewBoundsToFrameTransform - 7195.IBPluginDependency - 7195.IBViewBoundsToFrameTransform - 7196.IBPluginDependency - 7196.IBViewBoundsToFrameTransform - 7197.IBPluginDependency - 7197.IBViewBoundsToFrameTransform - 7198.IBPluginDependency - 7199.IBPluginDependency 72.IBPluginDependency 72.ImportedFromIB2 - 7200.IBEditorWindowLastContentRect - 7200.IBPluginDependency - 7201.IBPluginDependency - 7202.IBPluginDependency - 7203.IBPluginDependency - 7204.IBPluginDependency 7210.IBPluginDependency 7210.IBViewBoundsToFrameTransform 7211.IBPluginDependency @@ -42069,6 +41949,17 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 7729.IBViewBoundsToFrameTransform 7730.IBPluginDependency 7740.IBPluginDependency + 7759.IBPluginDependency + 7759.IBViewBoundsToFrameTransform + 7760.IBPluginDependency + 7761.IBPluginDependency + 7762.IBPluginDependency + 7765.IBNumberFormatterBehaviorMetadataKey + 7765.IBNumberFormatterLocalizesFormatMetadataKey + 7765.IBPluginDependency + 7766.IBPluginDependency + 7766.IBViewBoundsToFrameTransform + 7767.IBPluginDependency 783.IBPluginDependency 784.IBEditorWindowLastContentRect 784.IBPluginDependency @@ -42574,9 +42465,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{1389, 431}, {213, 198}} + {{1388, 659}, {213, 198}} com.apple.InterfaceBuilder.CocoaPlugin - {{1389, 431}, {213, 198}} + {{1388, 659}, {213, 198}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -45389,9 +45280,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1202, 1031}, {350, 125}} com.apple.InterfaceBuilder.CocoaPlugin - {{1017, 180}, {600, 376}} + {{1003, 212}, {620, 267}} com.apple.InterfaceBuilder.CocoaPlugin - {{1017, 180}, {600, 376}} + {{1003, 212}, {620, 267}} com.apple.InterfaceBuilder.CocoaPlugin {{632, 301}, {516, 283}} @@ -45401,11 +45292,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - AUGIAABDTwAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - AUGIAABDtgAAA + AUGIAABDVQAAA com.apple.InterfaceBuilder.CocoaPlugin @@ -45413,18 +45300,18 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin - P4AAAL+AAABChgAAwggAAA + P4AAAL+AAABDAgAAwfgAAA com.apple.InterfaceBuilder.CocoaPlugin - P4AAAL+AAABBkAAAwrQAAA + P4AAAL+AAABBkAAAwxEAAA ToolTip ToolTip - Use a physical microphone or other other sound input device connected to your Mac. [NOT YET IMPLEMENTED IN THIS VERSION] + Predefined noise samples that simulate sounds like speaking into the microphone. (Some games, such as "The Legend of Zelda: Spirit Tracks," work especially well with this.) com.apple.InterfaceBuilder.CocoaPlugin @@ -45434,7 +45321,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA ToolTip - Predefined noise samples that simulate sounds like blowing into the microphone. (Some games, such as "The Legend of Zelda: Spirit Tracks," work especially well with this.) + Randomly generated white noise that simulates sounds like blowing into the microphone. com.apple.InterfaceBuilder.CocoaPlugin @@ -45443,7 +45330,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA ToolTip - Randomly generated white noise that simulates sounds like blowing into the microphone. May also be useful if a game needs you to speak into the microphone. + Generated pure sine wave tone. Can be adjusted for frequency. @@ -45451,41 +45338,13 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA ToolTip - Use a sound file. (Whenever the microphone is activated, the sound will begin at the start of the file.) [NOT YET IMPLEMENTED IN THIS VERSION] + Predefined samples loaded from an audio file. (Whenever the Microphone command is deactivated, sample reading will be reset to the beginning of the file.) com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABDVwAAwegAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBgAAAwsoAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - AUGQAABC2AAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABCjgAAwxgAAA - - com.apple.InterfaceBuilder.CocoaPlugin - - P4AAAL+AAABBcAAAwxUAAA - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{443, 824}, {414, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABCrAAAwqAAAA @@ -45886,6 +45745,21 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDAAAAwnwAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDrwAAwiQAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin {{1234, 903}, {136, 163}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -46223,7 +46097,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - 7754 + 7770 @@ -47380,6 +47254,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES YES + audioFileChoose: + audioFileChooseNone: changeSpeed: closeProfileRenameSheet: closeProfileSheet: @@ -47411,12 +47287,16 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA id id id + id + id YES YES + audioFileChoose: + audioFileChooseNone: changeSpeed: closeProfileRenameSheet: closeProfileSheet: @@ -47434,6 +47314,14 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES + + audioFileChoose: + id + + + audioFileChooseNone: + id + changeSpeed: id @@ -48325,22 +48213,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA AppKit.framework/Headers/NSImageView.h - - NSLevelIndicator - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSLevelIndicator.h - - - - NSLevelIndicatorCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSLevelIndicatorCell.h - - NSMatrix NSControl diff --git a/desmume/src/cocoa/userinterface/EmuControllerDelegate.h b/desmume/src/cocoa/userinterface/EmuControllerDelegate.h index 863bedb73..f1b8daa9f 100644 --- a/desmume/src/cocoa/userinterface/EmuControllerDelegate.h +++ b/desmume/src/cocoa/userinterface/EmuControllerDelegate.h @@ -26,7 +26,7 @@ @class CocoaDSCheatManager; @class CheatWindowDelegate; @class DisplayWindowController; - +class AudioSampleBlockGenerator; @interface EmuControllerDelegate : NSObject { @@ -224,6 +224,9 @@ - (void) pauseCore; - (void) restoreCoreState; +- (AudioSampleBlockGenerator *) selectedAudioFileGenerator; +- (void) setSelectedAudioFileGenerator:(AudioSampleBlockGenerator *)theGenerator; + - (void) didEndFileMigrationSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; - (void) didEndSaveStateSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; - (void) didEndSaveStateSheetOpen:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; diff --git a/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm b/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm index 4f6f27674..09efbbdc8 100644 --- a/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm +++ b/desmume/src/cocoa/userinterface/EmuControllerDelegate.mm @@ -1004,7 +1004,14 @@ } else if (controlID == DSControllerState_Microphone) { - [[cdsCore cdsController] setMicrophoneState:theState inputMode:cmdAttr.intValue[1]]; + const NSInteger micMode = cmdAttr.intValue[1]; + [[cdsCore cdsController] setMicrophoneState:theState inputMode:micMode]; + + const float sineWaveFrequency = cmdAttr.floatValue[0]; + [[cdsCore cdsController] setSineWaveGeneratorFrequency:sineWaveFrequency]; + + NSString *audioFilePath = cmdAttr.object[0]; + [[cdsCore cdsController] setSelectedAudioFileGenerator:[inputManager audioFileGeneratorFromFilePath:audioFilePath]]; } else { @@ -1639,6 +1646,18 @@ [cdsCore restoreCoreState]; } +- (AudioSampleBlockGenerator *) selectedAudioFileGenerator +{ + CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; + return [[cdsCore cdsController] selectedAudioFileGenerator]; +} + +- (void) setSelectedAudioFileGenerator:(AudioSampleBlockGenerator *)theGenerator +{ + CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; + [[cdsCore cdsController] setSelectedAudioFileGenerator:theGenerator]; +} + - (void) didEndFileMigrationSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { NSURL *romURL = (NSURL *)contextInfo; diff --git a/desmume/src/cocoa/userinterface/InputManager.h b/desmume/src/cocoa/userinterface/InputManager.h index 703f80975..15ab070b1 100644 --- a/desmume/src/cocoa/userinterface/InputManager.h +++ b/desmume/src/cocoa/userinterface/InputManager.h @@ -23,6 +23,9 @@ #include #include +#include "mic_ext.h" +#undef BOOL + #define INPUT_HANDLER_STRING_LENGTH 256 enum InputAttributeState @@ -33,7 +36,6 @@ enum InputAttributeState }; @class EmuControllerDelegate; -@class CocoaDSController; @class InputManager; @class InputHIDManager; @@ -81,6 +83,7 @@ typedef std::vector CommandAttributesList; typedef std::tr1::unordered_map InputCommandMap; // Key = Input key in deviceCode:elementCode format, Value = CommandAttributes typedef std::tr1::unordered_map CommandAttributesMap; // Key = Command Tag, Value = CommandAttributes typedef std::tr1::unordered_map CommandSelectorMap; // Key = Command Tag, Value = Obj-C Selector +typedef std::tr1::unordered_map AudioFileSampleGeneratorMap; // Key = File path to audio file, Value = AudioSampleBlockGenerator #pragma mark - @interface InputHIDDevice : NSObject @@ -153,6 +156,7 @@ void HandleDeviceRemovalCallback(void *inContext, IOReturn inResult, void *inSen InputCommandMap commandMap; CommandAttributesMap defaultCommandAttributes; CommandSelectorMap commandSelector; + AudioFileSampleGeneratorMap audioFileGenerators; } @property (readonly) IBOutlet EmuControllerDelegate *emuControl; @@ -185,16 +189,20 @@ void HandleDeviceRemovalCallback(void *inContext, IOReturn inResult, void *inSen - (void) setMappedCommandAttributes:(const CommandAttributes *)cmdAttr deviceCode:(const char *)deviceCode elementCode:(const char *)elementCode; - (void) updateInputSettingsSummaryInDeviceInfoDictionary:(NSMutableDictionary *)deviceInfo commandTag:(const char *)commandTag; +- (OSStatus) loadAudioFileUsingPath:(NSString *)filePath; +- (AudioSampleBlockGenerator *) audioFileGeneratorFromFilePath:(NSString *)filePath; +- (void) updateAudioFileGenerators; + CommandAttributes NewDefaultCommandAttributes(const char *commandTag); CommandAttributes NewCommandAttributesForSelector(const char *commandTag, const SEL theSelector); CommandAttributes NewCommandAttributesForDSControl(const char *commandTag, const NSUInteger controlID); void UpdateCommandAttributesWithDeviceInfoDictionary(CommandAttributes *cmdAttr, NSDictionary *deviceInfo); -NSDictionary* DeviceInfoDictionaryWithCommandAttributes(const CommandAttributes *cmdAttr, - NSString *deviceCode, - NSString *deviceName, - NSString *elementCode, - NSString *elementName); +NSMutableDictionary* DeviceInfoDictionaryWithCommandAttributes(const CommandAttributes *cmdAttr, + NSString *deviceCode, + NSString *deviceName, + NSString *elementCode, + NSString *elementName); InputAttributesList InputManagerEncodeHIDQueue(const IOHIDQueueRef hidQueue); InputAttributes InputManagerEncodeKeyboardInput(const unsigned short keyCode, BOOL keyPressed); diff --git a/desmume/src/cocoa/userinterface/InputManager.mm b/desmume/src/cocoa/userinterface/InputManager.mm index f29b6f612..a39c070cc 100644 --- a/desmume/src/cocoa/userinterface/InputManager.mm +++ b/desmume/src/cocoa/userinterface/InputManager.mm @@ -23,6 +23,8 @@ #import "cocoa_input.h" #import "cocoa_util.h" +#include + /* Get the symbols for UpdateSystemActivity(). @@ -893,6 +895,7 @@ static std::tr1::unordered_map keyboardNameTable; / CommandAttributes cmdDSControlMic = NewCommandAttributesForDSControl("Microphone", DSControllerState_Microphone); cmdDSControlMic.intValue[1] = MICMODE_INTERNAL_NOISE; + cmdDSControlMic.floatValue[0] = 250.0f; CommandAttributes cmdLoadEmuSaveStateSlot = NewCommandAttributesForSelector("Load State Slot", commandSelector["Load State Slot"]); CommandAttributes cmdSaveEmuSaveStateSlot = NewCommandAttributesForSelector("Save State Slot", commandSelector["Save State Slot"]); @@ -1014,15 +1017,17 @@ static std::tr1::unordered_map keyboardNameTable; / } // Copy all command attributes into a new deviceInfo dictionary. - NSDictionary *newDeviceInfo = DeviceInfoDictionaryWithCommandAttributes(&cmdAttr, - [deviceInfo valueForKey:@"deviceCode"], - [deviceInfo valueForKey:@"deviceName"], - [deviceInfo valueForKey:@"elementCode"], - [deviceInfo valueForKey:@"elementName"]); + NSMutableDictionary *newDeviceInfo = DeviceInfoDictionaryWithCommandAttributes(&cmdAttr, + [deviceInfo valueForKey:@"deviceCode"], + [deviceInfo valueForKey:@"deviceName"], + [deviceInfo valueForKey:@"elementCode"], + [deviceInfo valueForKey:@"elementName"]); [self addMappingUsingDeviceInfoDictionary:newDeviceInfo commandAttributes:&cmdAttr]; } } + + [self updateAudioFileGenerators]; } - (void) addMappingUsingDeviceInfoDictionary:(NSDictionary *)deviceInfo commandAttributes:(const CommandAttributes *)cmdAttr @@ -1064,11 +1069,11 @@ static std::tr1::unordered_map keyboardNameTable; / return; } - NSDictionary *deviceInfo = DeviceInfoDictionaryWithCommandAttributes(cmdAttr, - [NSString stringWithCString:inputAttr->deviceCode encoding:NSUTF8StringEncoding], - [NSString stringWithCString:inputAttr->deviceName encoding:NSUTF8StringEncoding], - [NSString stringWithCString:inputAttr->elementCode encoding:NSUTF8StringEncoding], - [NSString stringWithCString:inputAttr->elementName encoding:NSUTF8StringEncoding]); + NSMutableDictionary *deviceInfo = DeviceInfoDictionaryWithCommandAttributes(cmdAttr, + [NSString stringWithCString:inputAttr->deviceCode encoding:NSUTF8StringEncoding], + [NSString stringWithCString:inputAttr->deviceName encoding:NSUTF8StringEncoding], + [NSString stringWithCString:inputAttr->elementCode encoding:NSUTF8StringEncoding], + [NSString stringWithCString:inputAttr->elementName encoding:NSUTF8StringEncoding]); [self addMappingUsingDeviceInfoDictionary:deviceInfo commandAttributes:cmdAttr]; } @@ -1119,8 +1124,7 @@ static std::tr1::unordered_map keyboardNameTable; / [self removeMappingUsingDeviceCode:deviceCode elementCode:elementCode]; // Map the input. - const std::string inputKey = std::string(deviceCode) + ":" + std::string(elementCode); - commandMap[inputKey] = *cmdAttr; + [self setMappedCommandAttributes:cmdAttr deviceCode:deviceCode elementCode:elementCode]; } - (void) removeMappingUsingDeviceCode:(const char *)deviceCode elementCode:(const char *)elementCode @@ -1131,12 +1135,7 @@ static std::tr1::unordered_map keyboardNameTable; / } const std::string inputKey = std::string(deviceCode) + ":" + std::string(elementCode); - - InputCommandMap::iterator it = commandMap.find(inputKey); - if (it != commandMap.end()) - { - commandMap.erase(it); - } + commandMap.erase(inputKey); for (NSString *inputCommandTag in inputMappings) { @@ -1312,7 +1311,7 @@ static std::tr1::unordered_map keyboardNameTable; / - (void) updateInputSettingsSummaryInDeviceInfoDictionary:(NSMutableDictionary *)deviceInfo commandTag:(const char *)commandTag { - NSString *inputSummary = @""; + NSString *inputSummary = nil; if (strncmp(commandTag, "Touch", INPUT_HANDLER_STRING_LENGTH) == 0) { @@ -1341,14 +1340,22 @@ static std::tr1::unordered_map keyboardNameTable; / inputSummary = NSSTRING_INPUTPREF_MIC_INTERNAL_NOISE; break; - case MICMODE_SOUND_FILE: - inputSummary = @"Sound File:"; + case MICMODE_AUDIO_FILE: + inputSummary = (NSString *)[deviceInfo valueForKey:@"object1"]; + if (inputSummary == nil) + { + inputSummary = NSSTRING_INPUTPREF_MIC_AUDIO_FILE_NONE_SELECTED; + } break; case MICMODE_WHITE_NOISE: inputSummary = NSSTRING_INPUTPREF_MIC_WHITE_NOISE; break; + case MICMODE_SINE_WAVE: + inputSummary = [NSString stringWithFormat:NSSTRING_INPUTPREF_MIC_SINE_WAVE, [(NSNumber *)[deviceInfo valueForKey:@"floatValue0"] floatValue]]; + break; + case MICMODE_PHYSICAL: inputSummary = @"Physical:"; break; @@ -1430,9 +1437,171 @@ static std::tr1::unordered_map keyboardNameTable; / } } + if (inputSummary == nil) + { + inputSummary = @""; + } + [deviceInfo setObject:inputSummary forKey:@"inputSettingsSummary"]; } +- (OSStatus) loadAudioFileUsingPath:(NSString *)filePath +{ + OSStatus error = noErr; + + if (filePath == nil) + { + error = 1; + return error; + } + + // Check if the audio file is already loaded. If it is, don't load it again. + std::string filePathStr = std::string([filePath cStringUsingEncoding:NSUTF8StringEncoding]); + for (AudioFileSampleGeneratorMap::iterator it=audioFileGenerators.begin(); it!=audioFileGenerators.end(); ++it) + { + if (it->first.find(filePathStr) != std::string::npos) + { + return error; + } + } + + // Open the audio file using the file URL. + NSURL *fileURL = [NSURL fileURLWithPath:filePath isDirectory:NO]; + if (fileURL == nil) + { + error = 1; + return error; + } + + ExtAudioFileRef audioFile; + error = ExtAudioFileOpenURL((CFURLRef)fileURL, &audioFile); + if (error != noErr) + { + return error; + } + + // Create an ASBD of the DS mic audio format. + AudioStreamBasicDescription outputFormat; + outputFormat.mSampleRate = MIC_SAMPLE_RATE; + outputFormat.mFormatID = kAudioFormatLinearPCM; + outputFormat.mFormatFlags = kAudioFormatFlagIsPacked; + outputFormat.mBytesPerPacket = 1; + outputFormat.mFramesPerPacket = 1; + outputFormat.mBytesPerFrame = 1; + outputFormat.mChannelsPerFrame = 1; + outputFormat.mBitsPerChannel = 8; + + error = ExtAudioFileSetProperty(audioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat); + if (error != noErr) + { + return error; + } + + SInt64 fileLengthFrames = 0; + UInt32 propertySize = sizeof(fileLengthFrames); + + error = ExtAudioFileGetProperty(audioFile, kExtAudioFileProperty_FileLengthFrames, &propertySize, &fileLengthFrames); + if (error != noErr) + { + return error; + } + + // Create a new audio file generator. + audioFileGenerators[filePathStr] = AudioSampleBlockGenerator(); + AudioSampleBlockGenerator &theGenerator = audioFileGenerators[filePathStr]; + u8 *buffer = theGenerator.allocate(fileLengthFrames); + + // Read the audio file and fill the generator's buffer. + const size_t convertBufferSize = 32 * 1024; + AudioBufferList convertedData; + convertedData.mNumberBuffers = 1; + convertedData.mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame; + convertedData.mBuffers[0].mDataByteSize = convertBufferSize; + convertedData.mBuffers[0].mData = buffer; + + UInt32 readFrames = convertBufferSize; + while (readFrames > 0) + { + ExtAudioFileRead(audioFile, &readFrames, &convertedData); + buffer += readFrames; + convertedData.mBuffers[0].mData = buffer; + } + + // Close the audio file. + ExtAudioFileDispose(audioFile); + + // Convert the audio buffer to 7-bit unsigned PCM. + buffer = theGenerator.getBuffer(); + for (SInt64 i = 0; i < fileLengthFrames; i++) + { + *(buffer+i) >>= 1; + } + + return error; +} + +- (AudioSampleBlockGenerator *) audioFileGeneratorFromFilePath:(NSString *)filePath +{ + BOOL isAudioFileLoaded = NO; + + if (filePath == nil) + { + return NULL; + } + + std::string filePathStr = std::string([filePath cStringUsingEncoding:NSUTF8StringEncoding]); + for (AudioFileSampleGeneratorMap::iterator it=audioFileGenerators.begin(); it!=audioFileGenerators.end(); ++it) + { + if (it->first.find(filePathStr) != std::string::npos) + { + isAudioFileLoaded = YES; + break; + } + } + + return (isAudioFileLoaded) ? &audioFileGenerators[filePathStr] : NULL; +} + +- (void) updateAudioFileGenerators +{ + NSMutableArray *inputList = (NSMutableArray *)[inputMappings valueForKey:@"Microphone"]; + + // Load any unloaded audio files + for (NSMutableArray *deviceInfo in inputList) + { + NSString *filePath = (NSString *)[deviceInfo valueForKey:@"object0"]; + [self loadAudioFileUsingPath:filePath]; + } + + // Unload any orphaned audio files + for (AudioFileSampleGeneratorMap::iterator it=audioFileGenerators.begin(); it!=audioFileGenerators.end(); ++it) + { + BOOL didFindKey = NO; + NSString *audioGeneratorKey = [NSString stringWithCString:it->first.c_str() encoding:NSUTF8StringEncoding]; + + for (NSMutableDictionary *deviceInfo in inputList) + { + NSString *deviceAudioFilePath = (NSString *)[deviceInfo valueForKey:@"object0"]; + if ([audioGeneratorKey isEqualToString:deviceAudioFilePath]) + { + didFindKey = YES; + break; + } + } + + if (!didFindKey) + { + AudioSampleBlockGenerator *selectedGenerator = [emuControl selectedAudioFileGenerator]; + if (selectedGenerator == &it->second) + { + [emuControl setSelectedAudioFileGenerator:NULL]; + } + + audioFileGenerators.erase(it); + } + } +} + CommandAttributes NewDefaultCommandAttributes(const char *commandTag) { CommandAttributes cmdAttr; @@ -1447,10 +1616,10 @@ CommandAttributes NewDefaultCommandAttributes(const char *commandTag) cmdAttr.floatValue[1] = 0; cmdAttr.floatValue[2] = 0; cmdAttr.floatValue[3] = 0; - cmdAttr.object[0] = 0; - cmdAttr.object[1] = 0; - cmdAttr.object[2] = 0; - cmdAttr.object[3] = 0; + cmdAttr.object[0] = nil; + cmdAttr.object[1] = nil; + cmdAttr.object[2] = nil; + cmdAttr.object[3] = nil; cmdAttr.useInputForIntCoord = false; cmdAttr.useInputForFloatCoord = false; @@ -1472,6 +1641,7 @@ CommandAttributes NewCommandAttributesForDSControl(const char *commandTag, const { CommandAttributes cmdAttr = NewCommandAttributesForSelector(commandTag, @selector(cmdUpdateDSController:)); cmdAttr.intValue[0] = controlID; + cmdAttr.floatValue[0] = 250.0f; return cmdAttr; } @@ -1491,6 +1661,10 @@ void UpdateCommandAttributesWithDeviceInfoDictionary(CommandAttributes *cmdAttr, NSNumber *floatValue1 = (NSNumber *)[deviceInfo valueForKey:@"floatValue1"]; NSNumber *floatValue2 = (NSNumber *)[deviceInfo valueForKey:@"floatValue2"]; NSNumber *floatValue3 = (NSNumber *)[deviceInfo valueForKey:@"floatValue3"]; + NSObject *object0 = [deviceInfo valueForKey:@"object0"]; + NSObject *object1 = [deviceInfo valueForKey:@"object1"]; + NSObject *object2 = [deviceInfo valueForKey:@"object2"]; + NSObject *object3 = [deviceInfo valueForKey:@"object3"]; NSNumber *useInputForIntCoord = (NSNumber *)[deviceInfo valueForKey:@"useInputForIntCoord"]; NSNumber *useInputForFloatCoord = (NSNumber *)[deviceInfo valueForKey:@"useInputForFloatCoord"]; NSNumber *useInputForScalar = (NSNumber *)[deviceInfo valueForKey:@"useInputForScalar"]; @@ -1503,18 +1677,23 @@ void UpdateCommandAttributesWithDeviceInfoDictionary(CommandAttributes *cmdAttr, if (floatValue0 != nil) cmdAttr->floatValue[0] = [floatValue0 floatValue]; if (floatValue1 != nil) cmdAttr->floatValue[1] = [floatValue1 floatValue]; if (floatValue2 != nil) cmdAttr->floatValue[2] = [floatValue2 floatValue]; - if (floatValue3 != nil) cmdAttr->floatValue[3] = [floatValue3 floatValue]; + if (floatValue3 != nil) cmdAttr->floatValue[3] = [floatValue3 floatValue]; if (useInputForIntCoord != nil) cmdAttr->useInputForIntCoord = [useInputForIntCoord boolValue]; if (useInputForFloatCoord != nil) cmdAttr->useInputForFloatCoord = [useInputForFloatCoord boolValue]; if (useInputForScalar != nil) cmdAttr->useInputForScalar = [useInputForScalar boolValue]; if (useInputForSender != nil) cmdAttr->useInputForSender = [useInputForSender boolValue]; + + cmdAttr->object[0] = object0; + cmdAttr->object[1] = object1; + cmdAttr->object[2] = object2; + cmdAttr->object[3] = object3; } -NSDictionary* DeviceInfoDictionaryWithCommandAttributes(const CommandAttributes *cmdAttr, - NSString *deviceCode, - NSString *deviceName, - NSString *elementCode, - NSString *elementName) +NSMutableDictionary* DeviceInfoDictionaryWithCommandAttributes(const CommandAttributes *cmdAttr, + NSString *deviceCode, + NSString *deviceName, + NSString *elementCode, + NSString *elementName) { if (cmdAttr == NULL || deviceCode == nil || @@ -1527,26 +1706,34 @@ NSDictionary* DeviceInfoDictionaryWithCommandAttributes(const CommandAttributes NSString *deviceInfoSummary = [[deviceName stringByAppendingString:@": "] stringByAppendingString:elementName]; - return [NSDictionary dictionaryWithObjectsAndKeys: - deviceCode, @"deviceCode", - deviceName, @"deviceName", - elementCode, @"elementCode", - elementName, @"elementName", - deviceInfoSummary, @"deviceInfoSummary", - @"", @"inputSettingsSummary", - [NSNumber numberWithInt:cmdAttr->intValue[0]], @"intValue0", - [NSNumber numberWithInt:cmdAttr->intValue[1]], @"intValue1", - [NSNumber numberWithInt:cmdAttr->intValue[2]], @"intValue2", - [NSNumber numberWithInt:cmdAttr->intValue[3]], @"intValue3", - [NSNumber numberWithFloat:cmdAttr->floatValue[0]], @"floatValue0", - [NSNumber numberWithFloat:cmdAttr->floatValue[1]], @"floatValue1", - [NSNumber numberWithFloat:cmdAttr->floatValue[2]], @"floatValue2", - [NSNumber numberWithFloat:cmdAttr->floatValue[3]], @"floatValue3", - [NSNumber numberWithBool:cmdAttr->useInputForIntCoord], @"useInputForIntCoord", - [NSNumber numberWithBool:cmdAttr->useInputForFloatCoord], @"useInputForFloatCoord", - [NSNumber numberWithBool:cmdAttr->useInputForScalar], @"useInputForScalar", - [NSNumber numberWithBool:cmdAttr->useInputForSender], @"useInputForSender", - nil]; + NSMutableDictionary *newDeviceInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + deviceCode, @"deviceCode", + deviceName, @"deviceName", + elementCode, @"elementCode", + elementName, @"elementName", + deviceInfoSummary, @"deviceInfoSummary", + @"", @"inputSettingsSummary", + [NSNumber numberWithInt:cmdAttr->intValue[0]], @"intValue0", + [NSNumber numberWithInt:cmdAttr->intValue[1]], @"intValue1", + [NSNumber numberWithInt:cmdAttr->intValue[2]], @"intValue2", + [NSNumber numberWithInt:cmdAttr->intValue[3]], @"intValue3", + [NSNumber numberWithFloat:cmdAttr->floatValue[0]], @"floatValue0", + [NSNumber numberWithFloat:cmdAttr->floatValue[1]], @"floatValue1", + [NSNumber numberWithFloat:cmdAttr->floatValue[2]], @"floatValue2", + [NSNumber numberWithFloat:cmdAttr->floatValue[3]], @"floatValue3", + [NSNumber numberWithBool:cmdAttr->useInputForIntCoord], @"useInputForIntCoord", + [NSNumber numberWithBool:cmdAttr->useInputForFloatCoord], @"useInputForFloatCoord", + [NSNumber numberWithBool:cmdAttr->useInputForScalar], @"useInputForScalar", + [NSNumber numberWithBool:cmdAttr->useInputForSender], @"useInputForSender", + nil]; + + // Set the object references last since these could be nil. + [newDeviceInfo setValue:cmdAttr->object[0] forKey:@"object0"]; + [newDeviceInfo setValue:cmdAttr->object[1] forKey:@"object1"]; + [newDeviceInfo setValue:cmdAttr->object[2] forKey:@"object2"]; + [newDeviceInfo setValue:cmdAttr->object[3] forKey:@"object3"]; + + return newDeviceInfo; } InputAttributesList InputManagerEncodeHIDQueue(const IOHIDQueueRef hidQueue) diff --git a/desmume/src/cocoa/userinterface/appDelegate.mm b/desmume/src/cocoa/userinterface/appDelegate.mm index 14ec07bba..9462c895c 100644 --- a/desmume/src/cocoa/userinterface/appDelegate.mm +++ b/desmume/src/cocoa/userinterface/appDelegate.mm @@ -29,7 +29,6 @@ #import "cocoa_firmware.h" #import "cocoa_globals.h" #import "cocoa_input.h" -#import "cocoa_mic.h" #import "cocoa_rom.h" #import "cocoa_util.h" @@ -172,8 +171,7 @@ [cdsCoreController setContent:newCore]; // Init the DS controller and microphone. - CocoaDSMic *newMic = [[[CocoaDSMic alloc] init] autorelease]; - CocoaDSController *newController = [[[CocoaDSController alloc] initWithMic:newMic] autorelease]; + CocoaDSController *newController = [[[CocoaDSController alloc] init] autorelease]; [newCore setCdsController:newController]; // Init the DS speakers. diff --git a/desmume/src/cocoa/userinterface/inputPrefsView.h b/desmume/src/cocoa/userinterface/inputPrefsView.h index 87566584b..93fac967a 100644 --- a/desmume/src/cocoa/userinterface/inputPrefsView.h +++ b/desmume/src/cocoa/userinterface/inputPrefsView.h @@ -49,6 +49,7 @@ InputManager *inputManager; NSString *configInputTargetID; NSMutableDictionary *configInputList; + NSMutableDictionary *inputSettingsInEdit; NSDictionary *inputSettingsMappings; @@ -76,6 +77,7 @@ @property (readonly) IBOutlet InputManager *inputManager; @property (retain) NSString *configInputTargetID; +@property (retain) NSMutableDictionary *inputSettingsInEdit; - (void) initSettingsSheets; - (void) populateInputProfileMenu; @@ -106,4 +108,7 @@ - (IBAction) closeProfileSheet:(id)sender; - (IBAction) closeProfileRenameSheet:(id)sender; +- (IBAction) audioFileChoose:(id)sender; +- (IBAction) audioFileChooseNone:(id)sender; + @end diff --git a/desmume/src/cocoa/userinterface/inputPrefsView.mm b/desmume/src/cocoa/userinterface/inputPrefsView.mm index bfc30399a..a2cb29560 100644 --- a/desmume/src/cocoa/userinterface/inputPrefsView.mm +++ b/desmume/src/cocoa/userinterface/inputPrefsView.mm @@ -46,6 +46,7 @@ @synthesize inputProfileRenameSheet; @synthesize inputManager; @dynamic configInputTargetID; +@synthesize inputSettingsInEdit; - (id)initWithFrame:(NSRect)frame { @@ -69,6 +70,7 @@ configInputTargetID = nil; configInputList = [[NSMutableDictionary alloc] initWithCapacity:128]; + inputSettingsInEdit = nil; return self; } @@ -221,6 +223,12 @@ [inputManager addMappingUsingInputAttributes:inputAttr commandAttributes:&cmdAttr]; [inputManager writeDefaultsInputMappings]; + // If we're dealing with a Microphone command, update the audio file generators list. + if ([commandTag isEqualToString:@"Microphone"]) + { + [inputManager updateAudioFileGenerators]; + } + // Deselect the row of the command tag. NSDictionary *inputMappings = [inputManager inputMappings]; NSArray *mappingList = (NSArray *)[inputMappings valueForKey:[self configInputTargetID]]; @@ -263,6 +271,12 @@ [inputManager updateInputSettingsSummaryInDeviceInfoDictionary:deviceInfo commandTag:cmdAttr.tag]; [inputManager setMappedCommandAttributes:&cmdAttr deviceCode:devCode elementCode:elCode]; [inputManager writeDefaultsInputMappings]; + + // If we're dealing with a Microphone command, update the audio file generators list. + if (strncmp(cmdAttr.tag, "Microphone", INPUT_HANDLER_STRING_LENGTH) == 0) + { + [inputManager updateAudioFileGenerators]; + } } - (BOOL) doesProfileNameExist:(NSString *)profileName @@ -306,7 +320,8 @@ [sheet orderOut:self]; NSOutlineView *outlineView = (NSOutlineView *)contextInfo; - NSMutableDictionary *deviceInfo = (NSMutableDictionary *)[inputSettingsController content]; + NSMutableDictionary *editedDeviceInfo = (NSMutableDictionary *)[inputSettingsController content]; + NSMutableDictionary *deviceInfoInEdit = [self inputSettingsInEdit]; switch (returnCode) { @@ -314,8 +329,9 @@ break; case NSOKButton: - [self setMappingUsingDeviceInfoDictionary:deviceInfo]; - [outlineView reloadItem:deviceInfo reloadChildren:NO]; + [deviceInfoInEdit setDictionary:editedDeviceInfo]; + [self setMappingUsingDeviceInfoDictionary:deviceInfoInEdit]; + [outlineView reloadItem:deviceInfoInEdit reloadChildren:NO]; break; default: @@ -323,6 +339,7 @@ } [inputSettingsController setContent:nil]; + [self setInputSettingsInEdit:nil]; } - (void) didEndProfileSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo @@ -553,6 +570,10 @@ if ([item isKindOfClass:[NSDictionary class]]) { settingsSummary = [item valueForKey:@"inputSettingsSummary"]; + if (settingsSummary == nil) + { + settingsSummary = @""; + } } return settingsSummary; @@ -680,12 +701,18 @@ const NSInteger rowNumber = [outlineView clickedRow]; NSDictionary *deviceInfo = (NSDictionary *)[outlineView itemAtRow:rowNumber]; - NSMutableArray *inputList = (NSMutableArray *)[outlineView parentForItem:deviceInfo]; + NSArray *inputList = (NSArray *)[outlineView parentForItem:deviceInfo]; [inputManager removeMappingUsingDeviceCode:[(NSString *)[deviceInfo valueForKey:@"deviceCode"] cStringUsingEncoding:NSUTF8StringEncoding] elementCode:[(NSString *)[deviceInfo valueForKey:@"elementCode"] cStringUsingEncoding:NSUTF8StringEncoding]]; [inputManager writeDefaultsInputMappings]; [outlineView reloadItem:inputList reloadChildren:YES]; + + // If we're dealing with a Microphone command, update the audio file generators list. + if ([[inputManager commandTagFromInputList:inputList] isEqualToString:@"Microphone"]) + { + [inputManager updateAudioFileGenerators]; + } } - (IBAction) changeSpeed:(id)sender @@ -703,8 +730,8 @@ NSOutlineView *outlineView = (NSOutlineView *)sender; const NSInteger rowNumber = [outlineView clickedRow]; - NSMutableDictionary *item = (NSMutableDictionary *)[outlineView itemAtRow:rowNumber]; - NSString *commandTag = [inputManager commandTagFromInputList:[outlineView parentForItem:item]]; + [self setInputSettingsInEdit:(NSMutableDictionary *)[outlineView itemAtRow:rowNumber]]; + NSString *commandTag = [inputManager commandTagFromInputList:[outlineView parentForItem:[self inputSettingsInEdit]]]; NSWindow *theSheet = (NSWindow *)[inputSettingsMappings valueForKey:commandTag]; if (theSheet == nil) @@ -712,7 +739,7 @@ return; } - [inputSettingsController setContent:item]; + [inputSettingsController setContent:[NSMutableDictionary dictionaryWithDictionary:[self inputSettingsInEdit]]]; [NSApp beginSheet:theSheet modalForWindow:prefWindow @@ -746,7 +773,7 @@ [savedProfilesList addObject:newProfile]; - NSInteger profileIndex = _defaultProfileListCount + [savedProfilesList count] - 1; + const NSInteger profileIndex = _defaultProfileListCount + [savedProfilesList count] - 1; NSMenu *profileMenu = [inputProfileMenu menu]; NSMenuItem *newProfileMenuItem = [[[NSMenuItem alloc] initWithTitle:newProfileName action:@selector(profileSelect:) @@ -825,7 +852,7 @@ return; } - NSInteger profileIndex = [inputProfileMenu indexOfSelectedItem] - 1; + const NSInteger profileIndex = [inputProfileMenu indexOfSelectedItem] - 1; NSMenu *profileMenu = [inputProfileMenu menu]; [profileMenu removeItemAtIndex:[inputProfileMenu indexOfSelectedItem]]; @@ -855,7 +882,7 @@ - (IBAction) profileSelect:(id)sender { - NSInteger profileID = [CocoaDSUtil getIBActionSenderTag:sender]; + const NSInteger profileID = [CocoaDSUtil getIBActionSenderTag:sender]; NSArray *profileList = nil; if (profileID < 0 || profileID >= (NSInteger)(_defaultProfileListCount + [savedProfilesList count])) @@ -902,6 +929,71 @@ [NSApp endSheet:sheet returnCode:[CocoaDSUtil getIBActionSenderTag:sender]]; } +- (IBAction) audioFileChoose:(id)sender +{ + NSURL *selectedFileURL = nil; + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setCanChooseDirectories:NO]; + [panel setCanChooseFiles:YES]; + [panel setResolvesAliases:YES]; + [panel setAllowsMultipleSelection:NO]; + [panel setTitle:@"Select Audio File"]; + NSArray *fileTypes = [NSArray arrayWithObjects: + @"3gp", + @"3g2", + @"aac", + @"adts", + @"ac3", + @"aifc", + @"aiff", + @"aif", + @"amr", + @"caf", + @"mpeg", + @"mpa", + @"mp1", + @"mp2", + @"mp3", + @"mp4", + @"m4a", + @"snd", + @"au", + @"sd2", + @"wav", + nil]; + + // The NSOpenPanel method -(NSInt)runModalForDirectory:file:types: + // is deprecated in Mac OS X v10.6. +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 + [panel setAllowedFileTypes:fileTypes]; + const NSInteger buttonClicked = [panel runModal]; +#else + const NSInteger buttonClicked = [panel runModalForDirectory:nil file:nil types:fileTypes]; +#endif + + if (buttonClicked == NSFileHandlingPanelOKButton) + { + selectedFileURL = [[panel URLs] lastObject]; + if(selectedFileURL == nil) + { + return; + } + + NSString *selectedFilePath = [selectedFileURL path]; + NSMutableDictionary *editedDeviceInfo = (NSMutableDictionary *)[inputSettingsController content]; + [editedDeviceInfo setValue:selectedFilePath forKey:@"object0"]; + [editedDeviceInfo setValue:[selectedFilePath lastPathComponent] forKey:@"object1"]; + } +} + +- (IBAction) audioFileChooseNone:(id)sender +{ + NSMutableDictionary *editedDeviceInfo = (NSMutableDictionary *)[inputSettingsController content]; + [editedDeviceInfo setValue:nil forKey:@"object0"]; + [editedDeviceInfo setValue:nil forKey:@"object1"]; +} + #pragma mark NSControl Delegate Methods - (void)controlTextDidEndEditing:(NSNotification *)aNotification diff --git a/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm b/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm index 4ae81a42d..f4b30a7f4 100644 --- a/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm +++ b/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm @@ -24,7 +24,6 @@ #import "cocoa_globals.h" #import "cocoa_input.h" #import "cocoa_file.h" -#import "cocoa_mic.h" #import "cocoa_videofilter.h" #import "cocoa_util.h"