/** * Audio Module - Audio playback and management system * * Features: * - Audio playback with WAV files - Support for standard WAV audio format * - Audio streaming playback - Real-time audio stream processing * - Text-to-speech playback - TTS functionality for text conversion * - Volume control and range management - Precise volume control with range validation * - Playback interruption and cache management - Advanced playback control and resource management * * Usage: * - Audio playback service - Background music, sound effects, notifications * - TTS service - Voice announcements, accessibility features (not all devices support) * - Volume management - System-wide volume control with user-friendly interface * - Support cross-thread audio playback * - The WAV format should be Channels : 1, Sample Rate : approximately 24000, Precision : 16-bit, other formats need to be converted to this format * * Doc/Demo : https://github.com/DejaOS/DejaOS */ import { audioClass } from './libvbar-m-dxaudio.so' // Create audio object instance for native operations const audioObj = new audioClass(); // Export audio module interface const audio = {} // Playback status code constants audio.PLAY_CODE = { SUCCESS: 0, // Playback completed successfully FAILED: -1, // Playback operation failed QUEUE_IS_FULL: -2 // Playback queue is full, cannot add more audio } // Language type constants for TTS functionality audio.PLAY_TYPE = { CHINESE_DATA: 0, /** Chinese language TTS data */ ENGLISH_DATA: 1, /** English language TTS data */ } /** * Audio system initialization * @param {number} [volume=5] Volume level (0-10) - User-friendly volume range (0 means mute), default 5 * @param {number} [periodSize=512] Period size in samples - Audio processing granularity, default 512 * @param {number} [bufferSize=2048] Buffer size in samples - Audio buffer capacity, default 2048 * @throws {Error} If initialization fails - Throws error when audio system cannot be initialized * * Technical Details: * - periodSize: Controls audio processing latency. Smaller values (256,512) provide lower latency * but higher CPU usage. Larger values (1024,2048) reduce CPU usage but increase latency. * - bufferSize: Determines audio smoothness. Smaller values (1024,2048) use less memory but may * cause audio stuttering. Larger values (4096,8192) provide smoother playback but use more memory. * - Recommended configurations: * * Low latency: (256, 1024) - For real-time communication * * High quality: (1024, 4096) - For music playback * * Balanced: (512, 2048) - For general applications */ audio.init = function (volume = 5, periodSize = 512, bufferSize = 2048) { // Parameter validation validateNumber(volume, 'volume'); validateNumber(periodSize, 'periodSize'); validateNumber(bufferSize, 'bufferSize'); // Validate volume range (0-10 for user-friendly interface; 0 means mute) if (volume < 0 || volume > 10) { throw new Error("audio.init: 'volume' must be between 0 and 10"); } // Initialize audio system with specified parameters audioObj.audioInit(volume, periodSize, bufferSize) } /** * Audio system deinitialization * @returns {boolean} true if deinitialization successful, false otherwise * * Note: This function releases all audio resources and should be called * when the audio system is no longer needed to prevent resource leaks. */ audio.deinit = function () { return audioObj.audioDeinit() } /** * Get current audio volume level * @returns {number} Current volume level (0-10) - Mapped from hardware volume to user-friendly range (0 means mute) * * The returned value is automatically mapped from the hardware volume range * to the user-friendly 1-10 range for consistent interface experience. */ audio.getVolume = function () { return audioObj.audioGetVolume() } /** * Set audio volume level * @param {number} volume Volume level (0-10), required parameter (0 means mute) * @returns {boolean} true if volume set successfully, false otherwise * * Volume levels outside the valid range (1-10) will be automatically clamped * to the nearest valid value. The function maps user volume to hardware volume * internally for optimal audio quality. */ audio.setVolume = function (volume) { if (volume == undefined || volume == null) { throw new Error("audio.setVolume: 'volume' parameter should not be null") } if (volume < 0 || volume > 10) { throw new Error("audio.setVolume: 'volume' must be between 0 and 10") } return audioObj.audioSetVolume(volume) } /** * Play WAV audio file from file path * @param {string} path Absolute path to WAV file, required parameter * @returns {number} Playback status code (see audio.PLAY_CODE constants) * * File path should start with '/app/code/' and typically placed in the project's * resource directory (same level as src directory). Supports standard WAV format. * * Return values: * - 0: Playback started successfully * - -1: Playback failed * - -2: Playback queue is full */ audio.play = function (path) { if (!path) { throw new Error("audio.play: 'path' parameter should not be null") } return audioObj.audioPlayWav(path) } /** * Play audio from ArrayBuffer data (streaming audio) * @param {ArrayBuffer} buffer Audio data buffer, required parameter * @returns {number} Playback status code (see audio.PLAY_CODE constants) * * This function is useful for playing audio streams, real-time audio data, * or audio data received from network sources. The buffer should contain * valid WAV format audio data. */ audio.playWavData = function (buffer) { if (!buffer) { throw new Error("audio.playWavData: 'buffer' parameter should not be null") } return audioObj.audioPlayWavData(buffer) } /** * Play text using Text-to-Speech (TTS) functionality * @param {string} txt Text to be converted to speech, required parameter * @param {number} type Language type, required parameter (0: Chinese, 1: English) * @returns {number} Playback status code (see audio.PLAY_CODE constants) * * TTS functionality may not be supported on all devices. The function converts * the provided text to speech in the specified language and plays it through * the audio system. * * Language types: * - 0: Chinese (中文) * - 1: English (English) */ audio.playTxt = function (txt, type) { if (!txt) { throw new Error("audio.playTxt: 'txt' parameter should not be null") } if (typeof type !== 'number' || isNaN(type)) { throw new Error("audio.playTxt: 'type' parameter should not be null") } return audioObj.audioPlayTxt(txt, type) } /** * Interrupt currently playing audio * @returns {boolean} true if interruption successful, false otherwise * * This function immediately stops the currently playing audio without affecting * the playback queue. It's useful for emergency stops or when switching * between different audio sources. */ audio.interrupt = function () { return audioObj.audioPlayingInterrupt() } /** * Clear audio playback cache and queue * @returns {boolean} true if cache cleared successfully, false otherwise * * This function removes all pending audio from the playback queue and clears * the audio cache. It should be used when you want to completely reset the * audio playback state or free up memory resources. * * Note: This operation is mutually exclusive with playback functions and * should not be called while audio is actively playing. */ audio.clearCache = function () { return audioObj.audioClearPlayCache() } function validateNumber(value, name) { if (typeof value !== 'number' || isNaN(value)) { throw new TypeError(`${name} must be a valid number`); } } // Export audio module as default export export default audio;