voice-to-text-converter
Version:
A modern, lightweight Node.js package for speech-to-text conversion with support for multiple engines
194 lines • 6.69 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SUPPORTED_AUDIO_FORMATS = void 0;
exports.isSupportedAudioFormat = isSupportedAudioFormat;
exports.validateAudioFile = validateAudioFile;
exports.getAudioFileInfo = getAudioFileInfo;
exports.createAudioFileStream = createAudioFileStream;
exports.bufferToWav = bufferToWav;
exports.normalizeAudio = normalizeAudio;
exports.detectSilence = detectSilence;
exports.chunkAudioBuffer = chunkAudioBuffer;
exports.mergeAudioBuffers = mergeAudioBuffers;
exports.resampleAudio = resampleAudio;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
/**
* Supported audio file formats
*/
exports.SUPPORTED_AUDIO_FORMATS = ['.wav', '.mp3', '.ogg', '.flac', '.m4a'];
/**
* Check if a file is a supported audio format
*/
function isSupportedAudioFormat(filePath) {
const ext = path.extname(filePath).toLowerCase();
return exports.SUPPORTED_AUDIO_FORMATS.includes(ext);
}
/**
* Validate audio file exists and is supported
*/
function validateAudioFile(filePath) {
if (!fs.existsSync(filePath)) {
throw new Error(`Audio file not found: ${filePath}`);
}
if (!isSupportedAudioFormat(filePath)) {
throw new Error(`Unsupported audio format. Supported formats: ${exports.SUPPORTED_AUDIO_FORMATS.join(', ')}`);
}
}
function getAudioFileInfo(filePath) {
validateAudioFile(filePath);
const stats = fs.statSync(filePath);
const format = path.extname(filePath).toLowerCase().substring(1);
return {
size: stats.size,
format,
// Note: For detailed audio info, you'd typically use a library like 'node-ffprobe'
// This is a simplified implementation
};
}
/**
* Create a readable stream from an audio file
*/
function createAudioFileStream(filePath) {
validateAudioFile(filePath);
return fs.createReadStream(filePath);
}
/**
* Convert audio buffer to WAV format (simplified implementation)
*/
function bufferToWav(buffer, sampleRate = 16000, channels = 1) {
const length = buffer.length;
const arrayBuffer = new ArrayBuffer(44 + length);
const view = new DataView(arrayBuffer);
// WAV header
const writeString = (offset, string) => {
for (let i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
};
writeString(0, 'RIFF');
view.setUint32(4, 36 + length, true);
writeString(8, 'WAVE');
writeString(12, 'fmt ');
view.setUint32(16, 16, true);
view.setUint16(20, 1, true);
view.setUint16(22, channels, true);
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * channels * 2, true);
view.setUint16(32, channels * 2, true);
view.setUint16(34, 16, true);
writeString(36, 'data');
view.setUint32(40, length, true);
// Copy audio data
const uint8Array = new Uint8Array(arrayBuffer);
uint8Array.set(new Uint8Array(buffer), 44);
return Buffer.from(arrayBuffer);
}
/**
* Normalize audio volume
*/
function normalizeAudio(buffer, targetVolume = 0.8) {
const samples = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 2);
// Find peak amplitude
let peak = 0;
for (let i = 0; i < samples.length; i++) {
const abs = Math.abs(samples[i]);
if (abs > peak)
peak = abs;
}
if (peak === 0)
return buffer;
// Calculate normalization factor
const factor = (targetVolume * 32767) / peak;
// Apply normalization
for (let i = 0; i < samples.length; i++) {
samples[i] = Math.round(samples[i] * factor);
}
return Buffer.from(samples.buffer);
}
/**
* Detect silence in audio buffer
*/
function detectSilence(buffer, threshold = 500) {
const samples = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 2);
let sum = 0;
for (let i = 0; i < samples.length; i++) {
sum += Math.abs(samples[i]);
}
const average = sum / samples.length;
return average < threshold;
}
/**
* Split audio buffer into chunks
*/
function chunkAudioBuffer(buffer, chunkSize) {
const chunks = [];
for (let i = 0; i < buffer.length; i += chunkSize) {
const end = Math.min(i + chunkSize, buffer.length);
chunks.push(buffer.slice(i, end));
}
return chunks;
}
/**
* Merge multiple audio buffers
*/
function mergeAudioBuffers(buffers) {
const totalLength = buffers.reduce((sum, buffer) => sum + buffer.length, 0);
const merged = Buffer.alloc(totalLength);
let offset = 0;
for (const buffer of buffers) {
buffer.copy(merged, offset);
offset += buffer.length;
}
return merged;
}
/**
* Convert sample rate (basic implementation)
*/
function resampleAudio(buffer, fromRate, toRate) {
if (fromRate === toRate)
return buffer;
const samples = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 2);
const ratio = fromRate / toRate;
const newLength = Math.floor(samples.length / ratio);
const resampled = new Int16Array(newLength);
for (let i = 0; i < newLength; i++) {
const sourceIndex = Math.floor(i * ratio);
resampled[i] = samples[sourceIndex];
}
return Buffer.from(resampled.buffer);
}
//# sourceMappingURL=audio.js.map