git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

commit cdfcc4ca2d5bfe9aab2df10ffc13cc425abf086d
parent 6055092249767d903aab96de8990025f2abb7c7a
Author: Lior Halphon <LIJI32@gmail.com>
Date:   Sat, 21 May 2022 02:17:59 +0300

Audio recording in the Cocoa frontend

Diffstat:
ACocoa/AudioRecordingAccessoryView.xib51+++++++++++++++++++++++++++++++++++++++++++++++++++
MCocoa/Document.h2++
MCocoa/Document.m87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
MCocoa/MainMenu.xib9+++++++--
4 files changed, 139 insertions(+), 10 deletions(-)

diff --git a/Cocoa/AudioRecordingAccessoryView.xib b/Cocoa/AudioRecordingAccessoryView.xib @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="Document"> + <connections> + <outlet property="audioFormatButton" destination="knX-AW-zt5" id="fKt-eI-H0y"/> + <outlet property="audioRecordingAccessoryView" destination="c22-O7-iKe" id="XD8-Gi-qOC"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <customView id="c22-O7-iKe"> + <rect key="frame" x="0.0" y="0.0" width="354" height="36"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Atq-RE-328"> + <rect key="frame" x="18" y="10" width="56" height="16"/> + <autoresizingMask key="autoresizingMask"/> + <textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Format:" id="dso-NS-JlD"> + <font key="font" metaFont="system"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="knX-AW-zt5"> + <rect key="frame" x="81" y="4" width="256" height="25"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <popUpButtonCell key="cell" type="push" title="Apple AIFF" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="proportionallyDown" inset="2" selectedItem="M3Z-UN-VKZ" id="tLM-Di-Dy3"> + <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + <menu key="menu" id="gqn-SL-AA5"> + <items> + <menuItem title="Apple AIFF" state="on" tag="1" id="M3Z-UN-VKZ"/> + <menuItem title="RIFF WAVE" tag="2" id="zA0-Np-4XD"/> + <menuItem title="Raw PCM (Stereo 96KHz, 16-bit LE)" id="r9J-4k-XH5"/> + </items> + </menu> + </popUpButtonCell> + <connections> + <action selector="audioFormatChanged:" target="-2" id="I1k-d9-afp"/> + </connections> + </popUpButton> + </subviews> + <point key="canvasLocation" x="75" y="19"/> + </customView> + </objects> +</document> diff --git a/Cocoa/Document.h b/Cocoa/Document.h @@ -56,6 +56,8 @@ @property (readonly) GB_oam_info_t *oamInfo; @property uint8_t oamCount; @property uint8_t oamHeight; +@property (strong) IBOutlet NSView *audioRecordingAccessoryView; +@property (strong) IBOutlet NSPopUpButton *audioFormatButton; + (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale; -(uint8_t) readMemory:(uint16_t) addr; diff --git a/Cocoa/Document.m b/Cocoa/Document.m @@ -101,6 +101,9 @@ enum model { Document *slave; signed linkOffset; bool linkCableBit; + + NSSavePanel *_audioSavePanel; + bool _isRecordingAudio; } @property GBAudioClient *audioClient; @@ -1134,7 +1137,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) return !GB_debugger_is_stopped(&gb); } else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE) { - [(NSMenuItem*)anItem setState:anItem.tag == current_model]; + [(NSMenuItem *)anItem setState:anItem.tag == current_model]; } else if ([anItem action] == @selector(interrupt:)) { if (![[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) { @@ -1142,26 +1145,29 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) } } else if ([anItem action] == @selector(disconnectAllAccessories:)) { - [(NSMenuItem*)anItem setState:accessory == GBAccessoryNone]; + [(NSMenuItem *)anItem setState:accessory == GBAccessoryNone]; } else if ([anItem action] == @selector(connectPrinter:)) { - [(NSMenuItem*)anItem setState:accessory == GBAccessoryPrinter]; + [(NSMenuItem *)anItem setState:accessory == GBAccessoryPrinter]; } else if ([anItem action] == @selector(connectWorkboy:)) { - [(NSMenuItem*)anItem setState:accessory == GBAccessoryWorkboy]; + [(NSMenuItem *)anItem setState:accessory == GBAccessoryWorkboy]; } else if ([anItem action] == @selector(connectLinkCable:)) { - [(NSMenuItem*)anItem setState:[(NSMenuItem *)anItem representedObject] == master || + [(NSMenuItem *)anItem setState:[(NSMenuItem *)anItem representedObject] == master || [(NSMenuItem *)anItem representedObject] == slave]; } else if ([anItem action] == @selector(toggleCheats:)) { - [(NSMenuItem*)anItem setState:GB_cheats_enabled(&gb)]; + [(NSMenuItem *)anItem setState:GB_cheats_enabled(&gb)]; } else if ([anItem action] == @selector(toggleDisplayBackground:)) { - [(NSMenuItem*)anItem setState:!GB_is_background_rendering_disabled(&gb)]; + [(NSMenuItem *)anItem setState:!GB_is_background_rendering_disabled(&gb)]; } else if ([anItem action] == @selector(toggleDisplayObjects:)) { - [(NSMenuItem*)anItem setState:!GB_is_object_rendering_disabled(&gb)]; + [(NSMenuItem *)anItem setState:!GB_is_object_rendering_disabled(&gb)]; + } + else if ([anItem action] == @selector(toggleAudioRecording:)) { + [(NSMenuItem *)anItem setTitle:_isRecordingAudio? @"Stop Audio Recording" : @"Start Audio Recording…"]; } return [super validateUserInterfaceItem:anItem]; @@ -2388,5 +2394,70 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) }]; } +- (IBAction)toggleAudioRecording:(id)sender +{ + + bool shouldResume = running; + [self stop]; + if (_isRecordingAudio) { + _isRecordingAudio = false; + int error = GB_stop_audio_recording(&gb); + if (error) { + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:[NSString stringWithFormat:@"Could not finalize recording: %s", strerror(error)]]; + [alert setAlertStyle:NSAlertStyleCritical]; + [alert runModal]; + } + else { + [self.osdView displayText:@"Audio recording ended"]; + } + if (shouldResume) { + [self start]; + } + return; + } + _audioSavePanel = [NSSavePanel savePanel]; + if (!self.audioRecordingAccessoryView) { + [[NSBundle mainBundle] loadNibNamed:@"AudioRecordingAccessoryView" owner:self topLevelObjects:nil]; + } + _audioSavePanel.accessoryView = self.audioRecordingAccessoryView; + [self audioFormatChanged:self.audioFormatButton]; + + [_audioSavePanel beginSheetModalForWindow:self.mainWindow completionHandler:^(NSInteger result) { + if (result == NSModalResponseOK) { + [_audioSavePanel orderOut:self]; + int error = GB_start_audio_recording(&gb, _audioSavePanel.URL.fileSystemRepresentation, self.audioFormatButton.selectedTag); + if (error) { + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:[NSString stringWithFormat:@"Could not start recording: %s", strerror(error)]]; + [alert setAlertStyle:NSAlertStyleCritical]; + [alert runModal]; + } + else { + [self.osdView displayText:@"Audio recording started"]; + _isRecordingAudio = true; + } + } + if (shouldResume) { + [self start]; + } + _audioSavePanel = nil; + }]; +} + +- (IBAction)audioFormatChanged:(NSPopUpButton *)sender +{ + switch ((GB_audio_format_t)sender.selectedTag) { + case GB_AUDIO_FORMAT_RAW: + _audioSavePanel.allowedFileTypes = @[@"raw", @"pcm"]; + break; + case GB_AUDIO_FORMAT_AIFF: + _audioSavePanel.allowedFileTypes = @[@"aiff", @"aif", @"aifc"]; + break; + case GB_AUDIO_FORMAT_WAV: + _audioSavePanel.allowedFileTypes = @[@"wav"]; + break; + } +} @end diff --git a/Cocoa/MainMenu.xib b/Cocoa/MainMenu.xib @@ -370,9 +370,14 @@ </connections> </menuItem> <menuItem isSeparatorItem="YES" id="DPb-Sh-5tg"/> - <menuItem title="Mute Sound" keyEquivalent="m" id="1UK-8n-QPP"> + <menuItem title="Start Audio Recording…" keyEquivalent="A" id="1UK-8n-QPP"> <connections> - <action selector="mute:" target="-1" id="YE5-mi-Yzd"/> + <action selector="toggleAudioRecording:" target="-1" id="YE5-mi-Yzd"/> + </connections> + </menuItem> + <menuItem title="Mute Sound" keyEquivalent="m" id="zo0-Rh-wTu"> + <connections> + <action selector="mute:" target="-1" id="eK3-ea-ExJ"/> </connections> </menuItem> </items>

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.