Skip to content

Commit

Permalink
add Acoustic Echo Cancellation
Browse files Browse the repository at this point in the history
  • Loading branch information
lihaoyun6 committed May 21, 2024
1 parent ecff279 commit 6ec0b20
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 16 deletions.
3 changes: 2 additions & 1 deletion QuickRecorder/QuickRecorderApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, SCStreamDelegate, SCStreamOu
"recordWinSound": true,
"trimAfterRecord": false,
"showOnDock": true,
"showMenubar": false
"showMenubar": false,
"enableAEC": false
]
)

Expand Down
4 changes: 4 additions & 0 deletions QuickRecorder/RecordEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ extension AppDelegate {
}

let input = SCContext.audioEngine.inputNode
if ud.bool(forKey: "enableAEC") {
try? input.setVoiceProcessingEnabled(true)
input.voiceProcessingOtherAudioDuckingConfiguration.duckingLevel = .min
}
input.installTap(onBus: 0, bufferSize: 1024, format: input.inputFormat(forBus: 0)) {buffer, time in
if SCContext.micInput.isReadyForMoreMediaData && SCContext.startTime != nil {
SCContext.micInput.append(buffer.asSampleBuffer!)
Expand Down
2 changes: 2 additions & 0 deletions QuickRecorder/SCContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,10 @@ class SCContext {
if #available(macOS 13, *) { awInput.markAsFinished() }
if ud.bool(forKey: "recordMic") {
micInput.markAsFinished()
//try! audioEngine.stopAudioUnit()
audioEngine.inputNode.removeTap(onBus: 0)
audioEngine.stop()
try? audioEngine.inputNode.setVoiceProcessingEnabled(false)
}
vW.finishWriting {
startTime = nil
Expand Down
30 changes: 17 additions & 13 deletions QuickRecorder/ViewModel/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct SettingsView: View {
@AppStorage("showOnDock") private var showOnDock: Bool = true
@AppStorage("showMenubar") private var showMenubar: Bool = false
@AppStorage("remuxAudio") private var remuxAudio: Bool = true
@AppStorage("enableAEC") private var enableAEC: Bool = false

var body: some View {
VStack {
Expand All @@ -58,7 +59,7 @@ struct SettingsView: View {
Text("H.264").tag(Encoder.h264)
Text("H.265").tag(Encoder.h265)
}
.padding([.leading, .trailing], 10).padding(.bottom, 1.5)
.padding([.leading, .trailing], 10)
.disabled(withAlpha)
}.frame(maxWidth: .infinity).padding(.top, 10)
Toggle(isOn: $withAlpha) { Text("Recording with Alpha Channel") }
Expand All @@ -82,7 +83,7 @@ struct SettingsView: View {
Text("High - 256Kbps").tag(AudioQuality.high)
Text("Extreme - 320Kbps").tag(AudioQuality.extreme)
}
.padding([.leading, .trailing], 10).padding(.bottom, 5.5)
.padding([.leading, .trailing], 10).padding(.bottom, 6)
.disabled(audioFormat == .alac || audioFormat == .flac)
Picker("Format", selection: $audioFormat) {
Text("MP3").tag(AudioFormat.mp3)
Expand All @@ -92,12 +93,15 @@ struct SettingsView: View {
Text("Opus").tag(AudioFormat.opus)
}.padding([.leading, .trailing], 10)
}.frame(maxWidth: .infinity).padding(.top, 10)
Text("Opus doesn't support MP4, it will fall back to AAC")
.font(.footnote).foregroundColor(Color.gray).padding([.leading, .trailing], 6).fixedSize(horizontal: false, vertical: true)
Toggle(isOn: $remuxAudio) { Text("Mixdown the track from microphone") }
.padding([.leading, .trailing], 10).padding(.bottom, 9)
/*Text("Opus doesn't support MP4, it will fall back to AAC")
.font(.footnote).foregroundColor(Color.gray).padding([.leading, .trailing], 6).fixedSize(horizontal: false, vertical: true)*/
Toggle(isOn: $remuxAudio) { Text("Record Microphone to Main Track") }
.padding([.leading, .trailing], 10)
.toggleStyle(.checkbox)
.disabled(isMacOS12)
Toggle(isOn: $enableAEC) { Text("Enable Acoustic Echo Cancellation") }
.padding([.leading, .trailing], 10).padding(.bottom, 9)
.toggleStyle(.checkbox)
}
}.frame(width: 270)
VStack {
Expand All @@ -119,31 +123,31 @@ struct SettingsView: View {
.disabled(!isMacOS14)
}.frame(maxWidth: .infinity).padding(.top, 10)
ColorPicker("Set custom background color:", selection: $userColor)
.padding([.leading, .trailing], 10).padding(.bottom, 1)
.padding([.leading, .trailing], 10).padding(.bottom, 2.5)
.onChange(of: userColor) { userColor in
ud.setColor(userColor, forKey: "userColor")
}
Toggle(isOn: $trimAfterRecord) { Text("Open video trimmer after recording") }
.padding([.leading, .trailing], 10).padding(.bottom, 4)
.padding([.leading, .trailing], 10).padding(.bottom, 5)
.toggleStyle(.checkbox)
Toggle(isOn: $hideSelf) { Text("Exclude QuickRecorder itself") }
.padding([.leading, .trailing], 10).padding(.bottom, 4)
.padding([.leading, .trailing], 10).padding(.bottom, 5)
.toggleStyle(.checkbox)
Toggle(isOn: $includeMenuBar) { Text("Include MenuBar in Recording") }
.padding([.leading, .trailing], 10).padding(.bottom, 4)
.padding([.leading, .trailing], 10).padding(.bottom, 5)
.toggleStyle(.checkbox)
.disabled(isMacOS12)
Toggle(isOn: $highlightMouse) { Text("Highlight the mouse cursor") }
Toggle(isOn: $highlightMouse) { Text("Highlight the Mouse Cursor") }
.padding([.leading, .trailing], 10)
.toggleStyle(.checkbox)
//.onChange(of: highlightMouse) {_ in Task { if highlightMouse { hideSelf = false }}}
Text("Not available for \"Single Window Capture\"")
.font(.footnote).foregroundColor(Color.gray).padding([.leading,.trailing], 6).padding(.top, -7).fixedSize(horizontal: false, vertical: true)
.font(.footnote).foregroundColor(Color.gray).padding([.leading,.trailing], 6).padding(.top, -5).fixedSize(horizontal: false, vertical: true)
Toggle(isOn: $hideDesktopFiles) { Text("Exclude the \"Desktop Files\" layer") }
.padding([.leading, .trailing], 10)
.toggleStyle(.checkbox)
Text("If enabled, all files on the Desktop will be hidden from the video when recording.")
.font(.footnote).foregroundColor(Color.gray).padding([.leading,.trailing, .bottom], 6).padding(.top, -7).fixedSize(horizontal: false, vertical: true)
.font(.footnote).foregroundColor(Color.gray).padding([.leading,.trailing, .bottom], 6).padding(.top, -5).fixedSize(horizontal: false, vertical: true)

}
}.frame(width: 270)
Expand Down
Binary file modified QuickRecorder/it.lproj/Localizable.strings
Binary file not shown.
5 changes: 3 additions & 2 deletions QuickRecorder/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@
"Audio Settings" = "音频设置";
"Video Settings" = "视频设置";
"Exclude QuickRecorder itself" = "排除QuickRecorder窗口";
"Highlight the mouse cursor" = "为鼠标光标添加高亮效果";
"Highlight the Mouse Cursor" = "为鼠标光标添加高亮效果";
"Not available for \"Single Window Capture\"" = "此功能不适用于\"录制单个窗口\"的情况";
"Normal - 128Kbps" = "标准 - 128Kbps";
"Good - 192Kbps" = "优质 - 192Kbps";
"High - 256Kbps" = "高清 - 256Kbps";
"Extreme - 320Kbps" = "极致 - 320Kbps";
"Other Settings" = "其他设置";
"Opus doesn't support MP4, it will fall back to AAC" = "同时使用Opus和MP4格式时, 音频编码将回落至AAC";
"Mixdown the track from microphone" = "将麦克风声音混缩至主音轨";
"Record Microphone to Main Track" = "将麦克风录制到主音轨";
"If enabled, all files on the Desktop will be hidden from the video when recording." = "启用此选项后, 当录制\"屏幕画面\"或\"访达\"程序时, 桌面上的所有文件将会从录制画面中被隐藏.";
"These apps will be excluded when recording \"Screen\" or \"Screen Area\"\n* But if the app is launched after the recording starts, it cannot be excluded." = "在录制 \"全屏画面\" 或 \"屏幕区域\" 的时候将不会录制这些 App 的画面 (点 + 添加App)\n* 但如果列表中的 App 在录屏开始后才被启动, 则无法被排除在录制画面之外.";
"Exclude the \"Desktop Files\" layer" = "录制时排除所有桌面文件";
Expand Down Expand Up @@ -141,6 +141,7 @@
"Don't remind me again" = "不再提醒";
"OK" = "好";
"Failed to save file" = "保存文件时出错";
"Enable Acoustic Echo Cancellation" = "降低麦克风音频串扰";

// Please don't translate the following warning strings, it will make it difficult for me to read the logs
"failed to fetch file for size indicator: %@" = "获取文件大小失败: ";
Expand Down

0 comments on commit 6ec0b20

Please sign in to comment.