### Install native-audio-node Source: https://github.com/predict-woo/native-audio-node/blob/main/README.md Install the package using npm. Pre-built binaries are automatically installed, requiring no build tools. ```bash npm install native-audio-node ``` -------------------------------- ### Run Example Scripts Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Execute example scripts to verify changes after building the project. Use the `-d` flag to specify recording duration in seconds. ```bash node examples/record-system.mjs -d 3 ``` ```bash node examples/record-mic.mjs ``` ```bash node examples/test-devices.mjs ``` ```bash node examples/test-permission.mjs ``` -------------------------------- ### Install Native Audio Node Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/win32-arm64/README.md Install the main package to automatically include platform-specific binaries like this one. ```bash # Do this instead: npm install native-audio-node ``` -------------------------------- ### Quick Start: Record System Audio and Microphone Source: https://github.com/predict-woo/native-audio-node/blob/main/README.md Demonstrates how to initialize and start recording system audio and microphone input using the respective classes. Handles audio data chunks. ```typescript import { SystemAudioRecorder, MicrophoneRecorder } from 'native-audio-node' // Record system audio const systemRecorder = new SystemAudioRecorder({ sampleRate: 16000, chunkDurationMs: 100, }) systemRecorder.on('data', (chunk) => { console.log(`Received ${chunk.data.length} bytes`) }) await systemRecorder.start() // Record microphone const micRecorder = new MicrophoneRecorder({ sampleRate: 16000, gain: 0.8, }) micRecorder.on('data', (chunk) => { // Process audio }) await micRecorder.start() ``` -------------------------------- ### Install Workspace Dependencies Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Installs all dependencies for the entire workspace using pnpm. This command should be run at the root of the project. ```bash pnpm install # Install workspace deps ``` -------------------------------- ### Build Native Addon and TypeScript Source: https://github.com/predict-woo/native-audio-node/blob/main/README.md Commands to install dependencies, build the native addon, copy binaries, and compile TypeScript for the project. ```bash # Install dependencies pnpm install # Build everything (native + TypeScript) pnpm run build # Or build separately pnpm run build:native # Compile native addon pnpm run copy-binary # Copy to platform package pnpm run build:ts # Compile TypeScript ``` -------------------------------- ### Monorepo Directory Structure Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Illustrates the layout of the monorepo, including the main TypeScript package, platform-specific prebuilt binaries, and native implementation directories. No specific setup is required to view this structure. ```bash packages/ native-audio-node/ # Main TS package — edit src/ here darwin-arm64/ # macOS Apple Silicon prebuilt binary darwin-x64/ # macOS Intel prebuilt binary win32-x64/ # Windows x64 prebuilt binary win32-arm64/ # Windows ARM64 prebuilt binary native/ napi/audio_napi.cpp # Node-API wrapper (shared) macos/swift/ # macOS Swift implementation windows/ # WASAPI implementation scripts/copy-binary.js # Copies built .node into matching platform package CMakeLists.txt # cmake-js build config ``` -------------------------------- ### Device and Permission Management Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Methods for listing audio devices, getting default devices, and managing system audio and microphone permissions. ```APIDOC ## Device and Permission Management ### Description Provides utilities for interacting with audio devices and managing permissions for audio capture. ### Methods - **listDevices()**: Returns an array of available `AudioDevice` objects. - **getDefaultInputDevice()**: Returns the name of the default input audio device, or `null` if not available. - **getDefaultOutputDevice()**: Returns the name of the default output audio device, or `null` if not available. - **getSystemAudioPermissionStatus()**: Returns the status of system audio permission ('unknown', 'denied', or 'authorized'). - **isSystemAudioPermissionAvailable()**: Returns `true` if system audio permission can be checked, `false` otherwise. - **requestSystemAudioPermission(callback)**: Requests system audio permission from the user. The `callback` function is invoked upon completion. - **getMicPermissionStatus()**: Returns the status of microphone permission ('unknown', 'denied', or 'authorized'). - **requestMicPermission(callback)**: Requests microphone permission from the user. The `callback` function is invoked upon completion. - **openSystemSettings()**: Attempts to open the system's audio settings. Returns `true` if successful, `false` otherwise. ``` -------------------------------- ### Real-time Audio Processing with MicrophoneRecorder Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Process audio chunks in real-time from the microphone. This example calculates and logs the volume level (dB) for each chunk. ```typescript import { MicrophoneRecorder } from 'native-audio-node' const recorder = new MicrophoneRecorder({ sampleRate: 16000, chunkDurationMs: 50, // 50ms chunks for low latency }) recorder.on('data', (chunk) => { // Calculate RMS (volume level) const samples = new Int16Array(chunk.data.buffer) let sum = 0 for (const sample of samples) { sum += sample * sample } const rms = Math.sqrt(sum / samples.length) const db = 20 * Math.log10(rms / 32768) console.log(`Volume: ${db.toFixed(1)} dB`) }) await recorder.start() ``` -------------------------------- ### Abstract Base Class Pattern Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Defines an abstract base class for audio recorders, utilizing `protected` for subclass-accessible state and `private` for internal implementation details. Requires subclasses to implement the `start` method. ```typescript export abstract class BaseAudioRecorder { protected events = new EventEmitter() protected native: AudioRecorderNativeClass private pollInterval: ReturnType | null = null abstract start(): Promise } ``` -------------------------------- ### Microphone Activity Monitoring Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Monitor microphone activity to detect when it's in use and by which applications. This example also shows how to programmatically check the active processes. ```typescript import { MicrophoneActivityMonitor } from 'native-audio-node' const monitor = new MicrophoneActivityMonitor() monitor.on('change', (isActive, processes) => { if (isActive) { console.log('🎤 Microphone in use!') // macOS: identify which apps are using the mic if (processes.length > 0) { console.log('Apps using mic:') for (const proc of processes) { console.log(` - ${proc.name} (PID: ${proc.pid})`) } } } else { console.log('🔇 Microphone idle') } }) monitor.start() // Check state programmatically setInterval(() => { const processes = monitor.getActiveProcesses() if (processes.length > 0) { console.log('Currently recording:', processes.map(p => p.name).join(', ')) } }, 5000) ``` -------------------------------- ### AudioMetadata Type Definition Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Defines the structure for audio format information, emitted once after recording starts. ```typescript interface AudioMetadata { sampleRate: number // Hz (e.g., 48000, 16000) channelsPerFrame: number // 1 (mono) or 2 (stereo) bitsPerChannel: number // 32 (float) or 16 (int) isFloat: boolean // true = 32-bit float, false = 16-bit int encoding: string // "pcm_f32le" or "pcm_s16le" } ``` -------------------------------- ### Managing Audio Devices with native-audio-node Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Demonstrates how to list all audio devices and filter them by input or output capabilities. Also shows how to retrieve the system's default input and output devices. ```typescript import { listAudioDevices, getDefaultInputDevice, getDefaultOutputDevice } from 'native-audio-node' // List all audio devices const devices = listAudioDevices() // Get input devices only const microphones = devices.filter(d => d.isInput) // Get output devices only const speakers = devices.filter(d => d.isOutput) // Get default devices const defaultMic = getDefaultInputDevice() // Returns device UID or null const defaultSpeaker = getDefaultOutputDevice() // Returns device UID or null ``` -------------------------------- ### Instantiate MicrophoneRecorder Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Initialize a MicrophoneRecorder to capture audio from the microphone. Configuration options include sample rate, chunk duration, stereo recording, silence emission, device ID, and gain. ```typescript import { MicrophoneRecorder } from 'native-audio-node' const recorder = new MicrophoneRecorder(options?: MicrophoneRecorderOptions) ``` -------------------------------- ### Publish Native Audio Node Packages Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Commands for publishing packages. It's crucial to publish platform packages before the main package. Use `pnpm run publish:all` for publishing all packages or `pnpm run version:all` to bump versions across the workspace. ```bash pnpm run publish:all # pnpm -r publish --access public pnpm run version:all # Bump versions across all workspace packages ``` -------------------------------- ### Build Native Audio Node Project Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Commands for building the native-audio-node project. Includes options for full builds, native compilation (debug and release), cleaning, copying binaries, and TypeScript compilation. Use `pnpm run build` for a complete build. ```bash pnpm run build # Full: native + copy-binary + ts pnpm run build:native # cmake-js compile pnpm run build:native:debug # Debug symbols for lldb/gdb pnpm run rebuild # cmake-js rebuild (clean compile) pnpm run clean:native # cmake-js clean pnpm run copy-binary # Move built .node to platform package pnpm run build:ts # tsup build of main package pnpm run dev # tsup watch mode ``` -------------------------------- ### Instantiate SystemAudioRecorder Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Create a new instance of SystemAudioRecorder to capture system audio output. Options can be provided to configure sample rate, chunk duration, stereo recording, muting, silence emission, and process filtering. ```typescript import { SystemAudioRecorder } from 'native-audio-node' const recorder = new SystemAudioRecorder(options?: SystemAudioRecorderOptions) ``` -------------------------------- ### Build N-API Module with Node.js Headers Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md Use this command to build an N-API module using plain Node.js headers. The `--runtime=electron` flag is unnecessary for N-API modules as they provide a stable ABI across Node.js and Electron. ```bash npx cmake-js rebuild --arch=x64 # Uses Node.js 25.3.0 headers ``` -------------------------------- ### Publish Platform Packages Source: https://github.com/predict-woo/native-audio-node/blob/main/README.md Commands for publishing platform-specific packages and the main package to npm. Ensure platform packages are published first. ```bash # Publish platform packages (with binaries) pnpm -r publish --access public # Or individually cd packages/darwin-arm64 && npm publish --access public cd packages/native-audio-node && npm publish ``` -------------------------------- ### Build Native Audio Node Package Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Performs a full build of the native audio node package, including native compilation, binary copying, and TypeScript compilation. Use `build:native` for just native compilation. ```bash pnpm run build # Full: native + copy-binary + ts ``` -------------------------------- ### Device Management Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Functions for listing and retrieving default audio input and output devices. ```APIDOC ## Device Management ### Description Provides functions to interact with audio devices on the system. ### Functions - `listAudioDevices()`: Returns an array of all available `AudioDevice` objects. - `getDefaultInputDevice()`: Returns the unique identifier of the default input audio device, or `null` if none is set. - `getDefaultOutputDevice()`: Returns the unique identifier of the default output audio device, or `null` if none is set. ### Types #### `AudioDevice` Represents an audio device with its properties. ```typescript interface AudioDevice { id: string // Unique device identifier name: string // Human-readable name manufacturer?: string // Device manufacturer isDefault: boolean // Is system default device isInput: boolean // Supports input (microphone) isOutput: boolean // Supports output (speakers) sampleRate: number // Native sample rate channelCount: number // Number of channels } ``` ### Request Example ```javascript import { listAudioDevices, getDefaultInputDevice, getDefaultOutputDevice } from 'native-audio-node' // List all audio devices const devices = listAudioDevices() console.log('All devices:', devices) // Get input devices only const microphones = devices.filter(d => d.isInput) console.log('Microphones:', microphones) // Get output devices only const speakers = devices.filter(d => d.isOutput) console.log('Speakers:', speakers) // Get default devices const defaultMic = getDefaultInputDevice() console.log('Default microphone ID:', defaultMic) const defaultSpeaker = getDefaultOutputDevice() console.log('Default speaker ID:', defaultSpeaker) ``` ``` -------------------------------- ### Instantiate MicrophoneActivityMonitor Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Create a MicrophoneActivityMonitor to track microphone usage across applications. Options allow specifying the scope of monitoring and a fallback polling interval. ```typescript import { MicrophoneActivityMonitor } from 'native-audio-node' const monitor = new MicrophoneActivityMonitor(options?: MicrophoneActivityMonitorOptions) ``` -------------------------------- ### Fetch Node-API Include Path Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Executes a Node.js command to determine the include directory for the 'node-addon-api' module and adds it to the project's include directories. This ensures the native addon can find the necessary Node-API headers. ```cmake execute_process( COMMAND node -p "require('node-addon-api').include" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE NODE_ADDON_API_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REGEX REPLACE "[" ]" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR}) target_include_directories(${PROJECT_NAME} PRIVATE ${NODE_ADDON_API_DIR}) ``` -------------------------------- ### Native Audio Node Architecture Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Overview of the native audio node's architecture, illustrating the flow from the TypeScript API through the NAPI wrapper to platform-specific implementations (macOS and Windows). ```text TypeScript API | BaseAudioRecorder (EventEmitter, 10ms polling) | Native NAPI Wrapper (C++) | +--------------------+--------------------+ | macOS | Windows | | (Swift Bridge) | (WASAPI C++) | +--------------------+--------------------+ | | +--------------------+--------------------+ | AudioTapManager | WasapiCapture | | MicrophoneCapture | (Loopback/Mic) | +--------------------+--------------------+ | | Core Audio / AVFoundation WASAPI ``` -------------------------------- ### macOS Configuration: Platform Libraries and Sources Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Defines the libraries, linker paths, and frameworks required for the macOS build, including the Swift runtime and Core Audio frameworks. All platform-specific sources are handled by the Swift library. ```cmake set( PLATFORM_LIBS ${SWIFT_LIB_DIR}/libcoreaudio_swift.a "-L${SWIFT_LIB_PATH}" "-lswiftCore" "-lswiftFoundation" "-lswiftDarwin" "-lswiftDispatch" "-lswiftCoreFoundation" "-lswiftObjectiveC" "-framework CoreAudio" "-framework AudioToolbox" "-framework AVFoundation" "-framework Foundation" "-framework CoreFoundation" "-framework AppKit" ) set(PLATFORM_SOURCES "") # All macOS code is in Swift library set(PLATFORM_DEPENDENCIES swift_lib) ``` -------------------------------- ### Copy Native Binary Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Copies the compiled native `.node` binary into the appropriate platform-specific package directory. This is a necessary step before publishing platform packages. ```bash pnpm run copy-binary # Move built .node to platform package ``` -------------------------------- ### Build Native Code for Debugging Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Use this command to build the native components of the project with debugging symbols enabled. After building, you can attach a debugger like lldb (macOS) or gdb to the generated .node binary. ```bash pnpm run build:native:debug # Then attach lldb (macOS) or gdb to the .node binary ``` -------------------------------- ### NativeAddon Interface Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md This interface defines the methods available on the NativeAddon object for interacting with native audio functionalities. ```APIDOC ## NativeAddon Interface This interface defines the methods available on the NativeAddon object for interacting with native audio functionalities. ### Methods - **AudioRecorderNative**: A constructor for creating an AudioRecorderNative instance. - **startSystemAudio(options)**: Starts recording system audio. - **startMicrophone(options)**: Starts recording microphone audio. - **stop()**: Stops the current audio recording. - **isRunning()**: Returns a boolean indicating if recording is active. - **processEvents()**: Processes and returns native events. - **listDevices()**: Returns an array of available audio devices. - **getDefaultInputDevice()**: Returns the default input audio device name or null. - **getDefaultOutputDevice()**: Returns the default output audio device name or null. - **getSystemAudioPermissionStatus()**: Returns the status of system audio permission ('unknown', 'denied', 'authorized'). - **isSystemAudioPermissionAvailable()**: Returns a boolean indicating if system audio permission is available. - **requestSystemAudioPermission(callback)**: Requests system audio permission, executing the callback upon completion. - **getMicPermissionStatus()**: Returns the status of microphone permission ('unknown', 'denied', 'authorized'). - **requestMicPermission(callback)**: Requests microphone permission, executing the callback upon completion. - **openSystemSettings()**: Attempts to open system settings for audio permissions. ``` -------------------------------- ### Set C++ Standard and Include Directories Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Configures the C++ standard to C++17 and includes necessary directories for cmake-js and common N-API sources. ```cmake set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories(${CMAKE_JS_INC}) include_directories(native/include) ``` -------------------------------- ### Native Audio Node Package Structure Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Details the file structure within the main TypeScript package, `packages/native-audio-node/src/`. This includes entry points, platform detection, types, and implementation files for recording. ```bash packages/native-audio-node/src/ - index.ts — public exports - binding.ts — platform/arch detection + native loader - types.ts — public TS interfaces - base-recorder.ts — abstract base, polling loop - system-audio-recorder.ts, microphone-recorder.ts - devices.ts, permission.ts ``` -------------------------------- ### macOS Configuration: Swift Static Library Build Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Builds a universal Swift static library for macOS using `swiftc` and `lipo`. This command compiles Swift sources for both arm64 and x86_64 architectures and then merges them into a single library. ```cmake add_custom_command( OUTPUT ${SWIFT_LIB_DIR}/libcoreaudio_swift.a COMMAND swiftc -emit-library -static -module-name CoreAudioSwift -parse-as-library -O -target arm64-apple-macosx14.2 -o ${SWIFT_LIB_DIR}/libcoreaudio_swift_arm64.a ${SWIFT_SOURCES} COMMAND swiftc -emit-library -static -module-name CoreAudioSwift -parse-as-library -O -target x86_64-apple-macosx14.2 -o ${SWIFT_LIB_DIR}/libcoreaudio_swift_x86_64.a ${SWIFT_SOURCES} COMMAND lipo -create ${SWIFT_LIB_DIR}/libcoreaudio_swift_arm64.a ${SWIFT_LIB_DIR}/libcoreaudio_swift_x86_64.a -output ${SWIFT_LIB_DIR}/libcoreaudio_swift.a DEPENDS ${SWIFT_SOURCES} COMMENT "Building Swift static library (universal binary)" VERBATIM ) ``` -------------------------------- ### Electron Delay Load Hook for Windows Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md This C++ code implements a custom delay-load hook for Windows to resolve issues with native module loading in Electron. It eagerly initializes the module handle and ensures valid function pointers are returned, preventing crashes. Use this when experiencing crashes related to native modules in Electron on Windows. ```cpp static HMODULE g_node_module = NULL; static FARPROC WINAPI electronDelayLoadHook(unsigned int event, DelayLoadInfo* info) { if (event == dliStartProcessing) { // Eagerly get the main process handle g_node_module = GetModuleHandleA(NULL); return NULL; } if (event == dliNotePreLoadLibrary) { if (_stricmp(info->szDll, "node.exe") == 0 || _stricmp(info->szDll, "NODE.EXE") == 0) { return (FARPROC)g_node_module; } return NULL; } if (event == dliNotePreGetProcAddress) { // g_node_module is guaranteed non-NULL here return GetProcAddress(g_node_module, info->dlp.szProcName); } return NULL; } decltype(__pfnDliNotifyHook2) __pfnDliNotifyHook2 = electronDelayLoadHook; ``` -------------------------------- ### Process-Specific Recording with SystemAudioRecorder Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Record audio exclusively from a specified process ID. Note that on Windows, only the first PID in the list is considered. ```typescript import { SystemAudioRecorder } from 'native-audio-node' // Record only from a specific process const recorder = new SystemAudioRecorder({ includeProcesses: [12345], // Process ID // Note: On Windows, only the first PID is used }) await recorder.start() ``` -------------------------------- ### Include Directories Configuration Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Specifies the private include directories for the target project, including custom include paths for native code and Node-API, as well as the JavaScript runtime include path. ```cmake target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/native/include ${CMAKE_SOURCE_DIR}/native/napi ${CMAKE_JS_INC} ) ``` -------------------------------- ### SystemAudioRecorder Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Captures system audio output. Allows configuration of sample rate, chunk duration, stereo recording, muting, silence emission, and process filtering. ```APIDOC ## Class: SystemAudioRecorder ### Description Captures system audio output (everything playing through speakers/headphones). ### Constructor ```typescript new SystemAudioRecorder(options?: SystemAudioRecorderOptions) ``` ### Options - `sampleRate` (number): Target sample rate (e.g., 8000, 16000, 44100). Defaults to device native. - `chunkDurationMs` (number): Audio chunk duration in milliseconds (0-5000). Defaults to 200. - `stereo` (boolean): Record in stereo (true) or mono (false). Defaults to false. - `mute` (boolean): Mute system audio while recording (macOS only). Defaults to false. - `emitSilence` (boolean): Emit silent chunks when no audio is playing (Windows only). Defaults to true. - `includeProcesses` (number[]): Only capture audio from these process IDs (Windows: first PID only). - `excludeProcesses` (number[]): Exclude audio from these process IDs (Windows: first PID only). ### Methods - `start()`: Starts audio capture. Returns `Promise`. - `stop()`: Stops audio capture. Returns `Promise`. - `isActive()`: Checks if currently recording. Returns `boolean`. - `getMetadata()`: Gets current audio format info. Returns `AudioMetadata | null`. ``` -------------------------------- ### Build Native Addon Library Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Defines the main shared library for the native addon, incorporating Node-API sources and platform-specific source files. ```cmake add_library(${PROJECT_NAME} SHARED ${NAPI_SOURCES} ${PLATFORM_SOURCES} ) ``` -------------------------------- ### Link Libraries Configuration Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Links the necessary libraries to the target project, including the JavaScript runtime library and platform-specific libraries defined earlier. ```cmake target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB} ${PLATFORM_LIBS} ) ``` -------------------------------- ### Define N-API Sources Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Lists the C++ source files for the N-API implementation. ```cmake set( NAPI_SOURCES native/napi/audio_napi.cpp ) ``` -------------------------------- ### Windows Audio Capture Troubleshooting Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Troubleshooting steps for no audio capture on Windows. Verify your Windows version and check microphone privacy settings. ```text 1. Ensure Windows 10 version 2004 or later 2. Check **Settings > Privacy > Microphone** for mic access 3. For system audio, no permissions are needed ``` -------------------------------- ### Rebuild and Clean Native Code Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Rebuilds the native addon, performing a clean compile. Use `clean:native` to remove build artifacts. ```bash pnpm run rebuild # cmake-js rebuild (clean compile) ``` ```bash pnpm run clean:native # cmake-js clean ``` -------------------------------- ### Set Target Properties Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Configures the output properties for the target library, specifically setting the prefix to empty and the suffix to '.node' for Node.js compatibility. ```cmake set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node" ) ``` -------------------------------- ### Build TypeScript Package Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Compiles the main TypeScript package using tsup. Use `dev` for watch mode during development. ```bash pnpm run build:ts # tsup build of main package ``` ```bash pnpm run dev # tsup watch mode ``` -------------------------------- ### Windows Platform Configuration Source: https://github.com/predict-woo/native-audio-node/blob/main/CMakeLists.txt Configures build settings for Windows, including required NTDDI version and defines for Unicode support. This section is conditionally compiled for Windows platforms. ```cmake message(STATUS "Building for Windows") # Windows 10 2004+ required for process loopback add_compile_definitions( NTDDI_VERSION=NTDDI_WIN10_VB _WIN32_WINNT=0x0A00 UNICODE _UNICODE ) set(PLATFORM_SOURCES native/windows/wasapi_capture.cpp native/windows/windows_bridge.cpp ) set(PLATFORM_LIBS ole32 uuid propsys avrt mmdevapi ) set(PLATFORM_DEPENDENCIES "") # No custom build steps needed else() message(FATAL_ERROR "Unsupported platform. Only macOS and Windows are supported.") endif() ``` -------------------------------- ### N-API Delay-Load Resolution Logs Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md These logs indicate successful delay-load resolution of N-API symbols within the Electron process. All symbols should resolve to valid addresses. ```text DELAY LOAD: dliStartProcessing DELAY LOAD: Main module handle: 00007FF685FF0000 DELAY LOAD: dliNotePreLoadLibrary for node.exe DELAY LOAD: Returning main module handle 00007FF685FF0000 for node.exe DELAY LOAD: dliNotePreGetProcAddress for napi_open_handle_scope from node.exe DELAY LOAD: GetProcAddress(napi_open_handle_scope) = 00007FF686532E10 DELAY LOAD: dliNoteEndProcessing ``` -------------------------------- ### Build N-API Module for Electron Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md This command is used for building N-API modules specifically for Electron. It ensures correct runtime version and architecture are targeted. The custom hook definition in the `.cpp` file takes precedence over cmake-js's default hook. ```bash npx cmake-js rebuild --runtime=electron --runtime-version=37.10.3 --arch=x64 ``` -------------------------------- ### Prettier Configuration Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Configuration for Prettier, enforcing specific formatting rules such as trailing commas, no semicolons, single quotes, and a 120-column width. ```json { "trailingComma": "es5", "semi": false, "singleQuote": true, "printWidth": 120 } ``` -------------------------------- ### Checking and Requesting System Audio Permission Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Provides functions to check the status of system audio permission, open system settings, and ensure permission is granted. Note that behavior and availability differ between macOS and Windows. ```typescript import { getSystemAudioPermissionStatus, isSystemAudioPermissionAvailable, requestSystemAudioPermission, ensureSystemAudioPermission, openSystemSettings, PermissionError, } from 'native-audio-node' // Check current status // macOS: Returns 'unknown', 'denied', or 'authorized' // Windows: Always returns 'authorized' const status = getSystemAudioPermissionStatus() // Open system settings (macOS: Privacy pane, Windows: Sound settings) openSystemSettings() // Ensure permission is granted (throws PermissionError if denied on macOS) try { await ensureSystemAudioPermission() // Permission granted, safe to start recording } catch (err) { if (err instanceof PermissionError) { console.log('Permission status:', err.status) } } ``` -------------------------------- ### Build Native Compilation Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Compiles the native Node.js addon using cmake-js. Use `build:native:debug` to include debug symbols for easier debugging with tools like lldb or gdb. ```bash pnpm run build:native # cmake-js compile ``` ```bash pnpm run build:native:debug # Debug symbols for lldb/gdb ``` -------------------------------- ### Promise Wrapper for Async Callbacks Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Wraps callback-based native APIs in Promises to provide a modern asynchronous interface. This function specifically handles requesting system audio permissions. ```typescript export function requestSystemAudioPermission(): Promise { return new Promise((resolve) => { loadBinding().requestSystemAudioPermission(resolve) }) } ``` -------------------------------- ### Checking and Requesting Microphone Permission Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Utility functions for managing microphone access permissions. Includes checking status, requesting permission, and ensuring it's granted, with error handling for denied access. ```typescript import { getMicrophonePermissionStatus, requestMicrophonePermission, ensureMicrophonePermission, PermissionError, } from 'native-audio-node' // Check current status const status = getMicrophonePermissionStatus() // Request permission (shows system dialog if needed) const granted = await requestMicrophonePermission() // Or use convenience function try { await ensureMicrophonePermission() } catch (err) { if (err instanceof PermissionError) { console.log('Microphone access denied') } } ``` -------------------------------- ### Monitor Microphone Activity Events Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Set up event listeners for MicrophoneActivityMonitor to react to changes in microphone usage. The 'change' event provides aggregate activity and active processes, while 'deviceChange' reports on individual device status. An 'error' event is also available. ```typescript import { MicrophoneActivityMonitor } from 'native-audio-node' const monitor = new MicrophoneActivityMonitor() monitor.on('change', (isActive, processes) => { if (isActive) { console.log('Microphone in use!') // On macOS, processes contains apps using the mic for (const proc of processes) { console.log(` ${proc.name} (PID: ${proc.pid})`) } } else { console.log('Microphone idle') } }) monitor.on('deviceChange', (device, isActive) => { console.log(`${device.name}: ${isActive ? 'active' : 'inactive'}`) }) monitor.start() // Query current state anytime console.log('Is mic active?', monitor.isActive()) console.log('Active processes:', monitor.getActiveProcesses()) // Later... monitor.stop() ``` -------------------------------- ### System Audio Permission Management Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Functions for checking, requesting, and ensuring system-wide audio permissions. ```APIDOC ## System Audio Permission Management ### Description Manages permissions required for the application to access system audio functionalities. ### Functions - `getSystemAudioPermissionStatus()`: Returns the current status of system audio permission. On macOS, returns 'unknown', 'denied', or 'authorized'. On Windows, always returns 'authorized'. - `isSystemAudioPermissionAvailable()`: Checks if system audio permission management is available on the current platform. - `requestSystemAudioPermission()`: Requests system audio permission from the user. Returns a promise that resolves to a boolean indicating if permission was granted. - `ensureSystemAudioPermission()`: Ensures system audio permission is granted. Throws a `PermissionError` if permission is denied on macOS. - `openSystemSettings()`: Opens the relevant system settings panel for audio permissions (macOS: Privacy pane, Windows: Sound settings). ### Types #### `PermissionError` Custom error type for permission-related issues. ```typescript interface PermissionError extends Error { status: string // The permission status at the time of the error } ``` ### Request Example ```javascript import { getSystemAudioPermissionStatus, ensureSystemAudioPermission, openSystemSettings, PermissionError } from 'native-audio-node' // Check current status const status = getSystemAudioPermissionStatus() console.log('System audio permission status:', status) // Open system settings // openSystemSettings() // Ensure permission is granted try { await ensureSystemAudioPermission() console.log('System audio permission granted.') // Proceed with audio operations } catch (err) { if (err instanceof PermissionError) { console.error('Failed to get system audio permission:', err.message) console.log('Current status:', err.status) // Optionally, guide user to open settings // openSystemSettings() } else { console.error('An unexpected error occurred:', err) } } ``` ``` -------------------------------- ### Native Addon TypeScript Interface Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Defines the TypeScript interface for the native addon, outlining available methods for audio recording, device management, and permission handling. ```typescript interface NativeAddon { AudioRecorderNative: new () => { startSystemAudio(options): void startMicrophone(options): void stop(): void isRunning(): boolean processEvents(): NativeEvent[] } listDevices(): AudioDevice[] getDefaultInputDevice(): string | null getDefaultOutputDevice(): string | null getSystemAudioPermissionStatus(): 'unknown' | 'denied' | 'authorized' isSystemAudioPermissionAvailable(): boolean requestSystemAudioPermission(callback): void getMicPermissionStatus(): 'unknown' | 'denied' | 'authorized' requestMicPermission(callback): void openSystemSettings(): boolean } ``` -------------------------------- ### SEH Guard for N-API Calls Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md Use Structured Exception Handling (SEH) with `__try/__except` to catch exceptions during N-API calls, such as `napi_open_handle_scope`, and log the exception code. ```cpp static napi_handle_scope SafeOpenHandleScope(napi_env env) { napi_handle_scope scope = nullptr; __try { napi_status status = napi_open_handle_scope(env, &scope); } __except(EXCEPTION_EXECUTE_HANDLER) { DWORD code = GetExceptionCode(); DebugLog("SEH EXCEPTION! Code: 0x%08X", code); return nullptr; } return scope; } ``` -------------------------------- ### Debug Logging in C++ Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md Add `OutputDebugStringA` and `fprintf(stderr)` logging to trace execution flow and pinpoint crashes in C++ code. ```cpp DebugLog("AudioRecorderWrapper::Init: ENTERING"); DebugLog("AudioRecorderWrapper::Init: About to create HandleScope with env=%p", env); Napi::HandleScope scope(env); // <-- CRASH HERE DebugLog("AudioRecorderWrapper::Init: HandleScope created"); // Never reached ``` -------------------------------- ### MicrophoneRecorder Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Captures audio from microphone input devices. Supports configuration of sample rate, chunk duration, stereo recording, silence emission, device selection, and gain. ```APIDOC ## Class: MicrophoneRecorder ### Description Captures audio from microphone input devices. ### Constructor ```typescript new MicrophoneRecorder(options?: MicrophoneRecorderOptions) ``` ### Options - `sampleRate` (number): Target sample rate. Defaults to device native. - `chunkDurationMs` (number): Audio chunk duration in milliseconds. Defaults to 200. - `stereo` (boolean): Record in stereo or mono. Defaults to false. - `emitSilence` (boolean): Emit silent chunks when no audio (Windows only). Defaults to true. - `deviceId` (string): Device UID (from `listAudioDevices()`). Defaults to system default. - `gain` (number): Microphone gain (0.0-2.0). Defaults to 1.0. ``` -------------------------------- ### AudioRecorderNative Class Source: https://github.com/predict-woo/native-audio-node/blob/main/AGENTS.md Provides methods to control audio recording from system audio or microphone, check recording status, and process audio events. ```APIDOC ## AudioRecorderNative ### Description Represents an audio recorder that can capture audio from the system or microphone. ### Methods - **startSystemAudio(options)**: Starts recording system audio. - **startMicrophone(options)**: Starts recording audio from the microphone. - **stop()**: Stops the current audio recording. - **isRunning()**: Returns `true` if a recording is active, `false` otherwise. - **processEvents()**: Processes and returns any pending native audio events. ``` -------------------------------- ### Record System Audio Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Record system audio using the SystemAudioRecorder. Configure sample rate, chunk duration, and mute behavior. Listen for metadata and audio data chunks. ```typescript import { SystemAudioRecorder } from 'native-audio-node' const recorder = new SystemAudioRecorder({ sampleRate: 16000, // Resample to 16kHz chunkDurationMs: 100, // 100ms audio chunks mute: false, // Don't mute system audio (macOS only) }) recorder.on('metadata', (meta) => { console.log(`Format: ${meta.sampleRate}Hz, ${meta.bitsPerChannel}bit`) }) recorder.on('data', (chunk) => { // chunk.data is a Buffer containing raw PCM audio console.log(`Received ${chunk.data.length} bytes`) }) await recorder.start() // Record for 10 seconds setTimeout(async () => { await recorder.stop() }, 10000) ``` -------------------------------- ### Microphone Permission Management Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Functions for checking and requesting microphone access permissions. ```APIDOC ## Microphone Permission Management ### Description Manages permissions required for the application to access the user's microphone. ### Functions - `getMicrophonePermissionStatus()`: Returns the current status of microphone permission. - `requestMicrophonePermission()`: Requests microphone permission from the user. Returns a promise that resolves to a boolean indicating if permission was granted. - `ensureMicrophonePermission()`: Ensures microphone permission is granted. Throws a `PermissionError` if permission is denied. ### Types #### `PermissionError` Custom error type for permission-related issues. ```typescript interface PermissionError extends Error { status: string // The permission status at the time of the error } ``` ### Request Example ```javascript import { getMicrophonePermissionStatus, requestMicrophonePermission, ensureMicrophonePermission, PermissionError } from 'native-audio-node' // Check current status const status = getMicrophonePermissionStatus() console.log('Microphone permission status:', status) // Request permission try { const granted = await requestMicrophonePermission() if (granted) { console.log('Microphone permission granted.') // Proceed with microphone operations } else { console.log('Microphone permission denied by user.') } } catch (err) { if (err instanceof PermissionError) { console.error('Failed to request microphone permission:', err.message) console.log('Current status:', err.status) } else { console.error('An unexpected error occurred:', err) } } // Or use convenience function try { await ensureMicrophonePermission() console.log('Microphone permission ensured.') } catch (err) { if (err instanceof PermissionError) { console.error('Microphone access denied:', err.message) } } ``` ``` -------------------------------- ### MicrophoneActivityMonitor Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Monitors microphone usage by any application on the system. Detects when apps start/stop using the microphone and identifies which processes are recording. ```APIDOC ## Class: MicrophoneActivityMonitor ### Description Monitors microphone usage by any application on the system. Detects when apps start/stop using the microphone and identifies which processes are recording. ### Constructor ```typescript new MicrophoneActivityMonitor(options?: MicrophoneActivityMonitorOptions) ``` ### Options - `scope` ('all' | 'default'): Monitor all input devices or only the default. Defaults to 'all'. - `fallbackPollInterval` (number): Polling interval in ms when native events unavailable. Defaults to 2000. ### Methods - `start()`: Start monitoring microphone activity. Returns `void`. - `stop()`: Stop monitoring and release resources. Returns `void`. - `isActive()`: Check if any microphone is currently in use. Returns `boolean`. - `isRunning()`: Check if the monitor is currently running. Returns `boolean`. - `getActiveDevices()`: Get list of devices currently being used. Returns `AudioDevice[]`. - `getActiveProcesses()`: Get list of processes using the microphone. Returns `AudioProcess[]`. ### Events - `change`: Emitted when aggregate mic activity changed. Payload: `(isActive: boolean, processes: AudioProcess[])`. - `deviceChange`: Emitted when specific device activity changed. Payload: `(device: AudioDevice, isActive: boolean)`. - `error`: Emitted when an error occurred during monitoring. Payload: `(error: Error)`. ### Example ```typescript import { MicrophoneActivityMonitor } from 'native-audio-node' const monitor = new MicrophoneActivityMonitor() monitor.on('change', (isActive, processes) => { if (isActive) { console.log('Microphone in use!') for (const proc of processes) { console.log(` ${proc.name} (PID: ${proc.pid}) }) } else { console.log('Microphone idle') } }) monitor.on('deviceChange', (device, isActive) => { console.log(`${device.name}: ${isActive ? 'active' : 'inactive'}`) }) monitor.start() console.log('Is mic active?', monitor.isActive()) console.log('Active processes:', monitor.getActiveProcesses()) monitor.stop() ``` ``` -------------------------------- ### AudioDevice Type Definition Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Describes an audio device with its properties like ID, name, and capabilities. ```typescript interface AudioDevice { id: string // Unique device identifier name: string // Human-readable name manufacturer?: string // Device manufacturer isDefault: boolean // Is system default device isInput: boolean // Supports input (microphone) isOutput: boolean // Supports output (speakers) sampleRate: number // Native sample rate channelCount: number // Number of channels } ``` -------------------------------- ### TypeScript Imports Source: https://github.com/predict-woo/native-audio-node/blob/main/CLAUDE.md Use local imports with the `.js` extension as required by ESM, even for TypeScript source files. Group imports with external modules first, followed by a blank line, then local modules. ```typescript import { BaseAudioRecorder } from './base-recorder.js' import type { AudioChunk } from './types.js' ``` -------------------------------- ### macOS System Audio Recording Permission Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Steps to configure system audio recording permissions on macOS. Ensure your terminal application is added and enabled in System Settings. ```text 1. Open **System Settings > Privacy & Security > Screen & System Audio Recording** 2. Scroll to **"System Audio Recording Only"** section 3. Add and enable your terminal app 4. Restart the terminal app ``` -------------------------------- ### cmake-js Default Delay-Load Hook Source: https://github.com/predict-woo/native-audio-node/blob/main/docs/ELECTRON_WINDOWS_CRASH_FIX.md This C++ code implements a custom delay-load hook for N-API symbols on Windows. It attempts to resolve symbols by first checking 'node.dll' and then 'nw.dll', with a fallback to the main executable. This hook is part of the cmake-js build system. ```cpp static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) { if (event == dliNotePreGetProcAddress) { FARPROC ret = GetProcAddress(node_dll, info->dlp.szProcName); if (ret) return ret; ret = GetProcAddress(nw_dll, info->dlp.szProcName); return ret; } if (event == dliStartProcessing) { node_dll = GetModuleHandleA("node.dll"); // NULL in Electron nw_dll = GetModuleHandleA("nw.dll"); // NULL in Electron return NULL; } if (event == dliNotePreLoadLibrary) { if (_stricmp(info->szDll, "node.exe") != 0) return NULL; if (!node_dll) node_dll = GetModuleHandleA(NULL); // Fallback return (FARPROC)node_dll; } return NULL; } ``` -------------------------------- ### AudioProcess Type Definition Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Provides information about a process currently using audio input. ```typescript interface AudioProcess { pid: number // Process ID name: string // Process name (e.g., "Zoom", "node") bundleId: string // macOS bundle identifier (e.g., "us.zoom.xos"), empty on Windows } ``` -------------------------------- ### Record Microphone Audio Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Record audio from a microphone using the MicrophoneRecorder. List available devices and optionally specify a device ID. Configure sample rate and gain. ```typescript import { MicrophoneRecorder, listAudioDevices } from 'native-audio-node' // List available input devices const devices = listAudioDevices().filter(d => d.isInput) console.log('Available microphones:', devices.map(d => d.name)) const recorder = new MicrophoneRecorder({ sampleRate: 16000, gain: 0.8, // 80% gain (0.0-2.0) deviceId: devices[0].id // Optional: specific device }) recorder.on('data', (chunk) => { // Process microphone audio }) await recorder.start() ``` -------------------------------- ### macOS Microphone Permission Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Steps to grant microphone access to your terminal application on macOS. Restart the app if necessary after enabling permissions. ```text 1. Open **System Settings > Privacy & Security > Microphone** 2. Enable access for your terminal app 3. Restart the app if needed ``` -------------------------------- ### Audio Recorder Events Interface Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Defines the events emitted by audio recorder classes. These include data chunks, metadata, start/stop signals, and errors. ```typescript interface AudioRecorderEvents { data: (chunk: AudioChunk) => void metadata: (metadata: AudioMetadata) => void start: () => void stop: () => void error: (error: Error) => void } ``` -------------------------------- ### AudioChunk Type Definition Source: https://github.com/predict-woo/native-audio-node/blob/main/packages/native-audio-node/README.md Represents a chunk of raw PCM audio data. ```typescript interface AudioChunk { data: Buffer // Raw PCM audio bytes } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.