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.
This commit is contained in:
rogerman 2013-04-10 21:59:55 +00:00
parent cc767726aa
commit bd571202e1
29 changed files with 1509 additions and 1101 deletions

View File

@ -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 = "<group>"; };
AB213D43170CB141006DDB0F /* InputProfileController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputProfileController.h; sourceTree = "<group>"; };
AB213D44170CB141006DDB0F /* InputProfileController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InputProfileController.mm; sourceTree = "<group>"; };
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 = "<group>"; };
AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiosamplegenerator.cpp; sourceTree = "<group>"; };
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 = "<group>"; };
AB2F56EF1704C86900E28885 /* utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utilities.c; sourceTree = "<group>"; };
@ -1202,8 +1213,8 @@
ABD1FF7A1345ACFA00AF11D1 /* SndOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SndOut.cpp; sourceTree = "<group>"; };
ABD1FF7B1345ACFA00AF11D1 /* SndOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SndOut.h; sourceTree = "<group>"; };
ABD1FF9B1345ACFA00AF11D1 /* Timestretcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timestretcher.cpp; sourceTree = "<group>"; };
ABD9A46313DB99B300777194 /* cocoa_mic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_mic.h; sourceTree = "<group>"; };
ABD9A46413DB99B300777194 /* cocoa_mic.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_mic.mm; sourceTree = "<group>"; };
ABD9A46313DB99B300777194 /* mic_ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mic_ext.h; sourceTree = "<group>"; };
ABD9A46413DB99B300777194 /* mic_ext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mic_ext.cpp; sourceTree = "<group>"; };
ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = "<group>"; };
ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = "<group>"; };
ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = "<group>"; };
@ -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;
};

View File

@ -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 = "<group>"; };
ABA6574914511EC90077E5E9 /* cocoa_cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_cheat.h; sourceTree = "<group>"; };
ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_cheat.mm; sourceTree = "<group>"; };
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 = "<group>"; };
ABAD3E5A13AF1D6D00502E1E /* BPMDetect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BPMDetect.h; sourceTree = "<group>"; };
ABAD3E5B13AF1D6D00502E1E /* cpu_detect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu_detect.h; sourceTree = "<group>"; };
@ -862,6 +871,10 @@
ABD104141346652500AF11D1 /* sndOSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sndOSX.cpp; sourceTree = "<group>"; };
ABD104271346653B00AF11D1 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
ABD10452134666DD00AF11D1 /* DeSmuME_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeSmuME_Prefix.pch; sourceTree = "<group>"; };
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 = "<group>"; };
ABD1FF7B1345ACFA00AF11D1 /* SndOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SndOut.h; sourceTree = "<group>"; };
ABD1FF9B1345ACFA00AF11D1 /* Timestretcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timestretcher.cpp; sourceTree = "<group>"; };
ABD9A46313DB99B300777194 /* cocoa_mic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_mic.h; sourceTree = "<group>"; };
ABD9A46413DB99B300777194 /* cocoa_mic.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_mic.mm; sourceTree = "<group>"; };
ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = "<group>"; };
ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = "<group>"; };
ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = "<group>"; };
@ -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;
};

View File

@ -256,7 +256,9 @@
<key>inputSettingsSummary</key>
<string>Internal Noise Samples</string>
<key>intValue1</key>
<string>1</string>
<integer>1</integer>
<key>floatValue0</key>
<real>250</real>
</dict>
</array>
<key>Lid</key>
@ -371,7 +373,7 @@
<key>inputSettingsSummary</key>
<string>0.50x Speed</string>
<key>floatValue0</key>
<string>0.5</string>
<real>0.5</real>
</dict>
<dict>
<key>deviceInfoSummary</key>

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifdef __APPLE__
#include <Availability.h>
#include "utilities.h"
#endif // __APPLE__
#include "audiosamplegenerator.h"
#include <math.h>
#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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef _AUDIO_SAMPLE_GENERATOR_
#define _AUDIO_SAMPLE_GENERATOR_
#include <stdio.h>
#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_

View File

@ -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
};

View File

@ -18,8 +18,8 @@
#import <Cocoa/Cocoa.h>
#include <libkern/OSAtomic.h>
@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

View File

@ -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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#import <Cocoa/Cocoa.h>
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@ -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.

View File

@ -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 <libkern/OSAtomic.h>
#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;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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_

View File

@ -17,27 +17,29 @@
#import <Cocoa/Cocoa.h>
#import <OpenEmuBase/OEGameCore.h>
#import "OENDSSystemResponderClient.h"
#include <libkern/OSAtomic.h>
@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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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()

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@
@class CocoaDSCheatManager;
@class CheatWindowDelegate;
@class DisplayWindowController;
class AudioSampleBlockGenerator;
@interface EmuControllerDelegate : NSObject <NSUserInterfaceValidations>
{
@ -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;

View File

@ -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;

View File

@ -23,6 +23,9 @@
#include <string>
#include <vector>
#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<CommandAttributes> CommandAttributesList;
typedef std::tr1::unordered_map<std::string, CommandAttributes> InputCommandMap; // Key = Input key in deviceCode:elementCode format, Value = CommandAttributes
typedef std::tr1::unordered_map<std::string, CommandAttributes> CommandAttributesMap; // Key = Command Tag, Value = CommandAttributes
typedef std::tr1::unordered_map<std::string, SEL> CommandSelectorMap; // Key = Command Tag, Value = Obj-C Selector
typedef std::tr1::unordered_map<std::string, AudioSampleBlockGenerator> 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);

View File

@ -23,6 +23,8 @@
#import "cocoa_input.h"
#import "cocoa_util.h"
#include <AudioToolbox/AudioToolbox.h>
/*
Get the symbols for UpdateSystemActivity().
@ -893,6 +895,7 @@ static std::tr1::unordered_map<unsigned short, std::string> 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<unsigned short, std::string> 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<unsigned short, std::string> 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<unsigned short, std::string> 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<unsigned short, std::string> 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<unsigned short, std::string> 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<unsigned short, std::string> 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<unsigned short, std::string> 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)

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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"