/**
|
* 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;
|