From c3895b602cfa54cd1e40fbb94267640fa73efd7c Mon Sep 17 00:00:00 2001
From: erew123 <35898566+erew123@users.noreply.github.com>
Date: Thu, 18 Apr 2024 18:43:25 +0100
Subject: [PATCH] Hindi Support
---
system/admin.html | 2 +
system/at_admin/at_settings.html | 1 +
system/config/languages.json | 1 +
system/tts_generator/crunker.d.ts | 358 ++++++++++++------------
system/tts_generator/crunker.esm.js | 2 +-
system/tts_generator/tts_generator.html | 1 +
6 files changed, 185 insertions(+), 180 deletions(-)
diff --git a/system/admin.html b/system/admin.html
index 7a988dc..c4c03b0 100644
--- a/system/admin.html
+++ b/system/admin.html
@@ -304,6 +304,7 @@
+
@@ -2500,6 +2501,7 @@
en English fr French de German
+ hi Hindi hu Hungarian it Italian ja Japanese
diff --git a/system/at_admin/at_settings.html b/system/at_admin/at_settings.html
index ddf67a8..90434ec 100644
--- a/system/at_admin/at_settings.html
+++ b/system/at_admin/at_settings.html
@@ -124,6 +124,7 @@
+
diff --git a/system/config/languages.json b/system/config/languages.json
index 3b780e8..d7d061f 100644
--- a/system/config/languages.json
+++ b/system/config/languages.json
@@ -6,6 +6,7 @@
"English": "en",
"French": "fr",
"German": "de",
+ "Hindi": "hi",
"Hungarian": "hu",
"Italian": "it",
"Japanese": "ja",
diff --git a/system/tts_generator/crunker.d.ts b/system/tts_generator/crunker.d.ts
index 4422095..8ec0fe8 100644
--- a/system/tts_generator/crunker.d.ts
+++ b/system/tts_generator/crunker.d.ts
@@ -1,179 +1,179 @@
-export interface CrunkerConstructorOptions {
- /**
- * Sample rate for Crunker's internal audio context.
- *
- * @default 44100
- */
- sampleRate: number;
-}
-export type CrunkerInputTypes = string | File | Blob;
-/**
- * An exported Crunker audio object.
- */
-export interface ExportedCrunkerAudio {
- blob: Blob;
- url: string;
- element: HTMLAudioElement;
-}
-/**
- * Crunker is the simple way to merge, concatenate, play, export and download audio files using the Web Audio API.
- */
-export default class Crunker {
- private readonly _sampleRate;
- private readonly _context;
- /**
- * Creates a new instance of Crunker with the provided options.
- *
- * If `sampleRate` is not defined, it will auto-select an appropriate sample rate
- * for the device being used.
- */
- constructor({ sampleRate }?: Partial);
- /**
- * Creates Crunker's internal AudioContext.
- *
- * @internal
- */
- private _createContext;
- /**
- *
- * The internal AudioContext used by Crunker.
- */
- get context(): AudioContext;
- /**
- * Asynchronously fetches multiple audio files and returns an array of AudioBuffers.
- */
- fetchAudio(...filepaths: CrunkerInputTypes[]): Promise;
- /**
- * Merges (layers) multiple AudioBuffers into a single AudioBuffer.
- *
- * **Visual representation:**
- *
- * 
- */
- mergeAudio(buffers: AudioBuffer[]): AudioBuffer;
- /**
- * Concatenates multiple AudioBuffers into a single AudioBuffer.
- *
- * **Visual representation:**
- *
- * 
- */
- concatAudio(buffers: AudioBuffer[]): AudioBuffer;
- /**
- * Pads a specified AudioBuffer with silence from a specified start time,
- * for a specified length of time.
- *
- * Accepts float values as well as whole integers.
- *
- * @param buffer AudioBuffer to pad
- * @param padStart Time to start padding (in seconds)
- * @param seconds Duration to pad for (in seconds)
- */
- padAudio(buffer: AudioBuffer, padStart?: number, seconds?: number): AudioBuffer;
- /**
- * Slices an AudioBuffer from the specified start time to the end time, with optional fade in and out.
- *
- * @param buffer AudioBuffer to slice
- * @param start Start time (in seconds)
- * @param end End time (in seconds)
- * @param fadeIn Fade in duration (in seconds, default is 0)
- * @param fadeOut Fade out duration (in seconds, default is 0)
- */
- sliceAudio(buffer: AudioBuffer, start: number, end: number, fadeIn?: number, fadeOut?: number): AudioBuffer;
- /**
- * Plays the provided AudioBuffer in an AudioBufferSourceNode.
- */
- play(buffer: AudioBuffer): AudioBufferSourceNode;
- /**
- * Exports the specified AudioBuffer to a Blob, Object URI and HTMLAudioElement.
- *
- * Note that changing the MIME type does not change the actual file format. The
- * file format will **always** be a WAVE file due to how audio is stored in the
- * browser.
- *
- * @param buffer Buffer to export
- * @param type MIME type (default: `audio/wav`)
- */
- export(buffer: AudioBuffer, type?: string): ExportedCrunkerAudio;
- /**
- * Downloads the provided Blob.
- *
- * @param blob Blob to download
- * @param filename An optional file name to use for the download (default: `crunker`)
- */
- download(blob: Blob, filename?: string): HTMLAnchorElement;
- /**
- * Executes a callback if the browser does not support the Web Audio API.
- *
- * Returns the result of the callback, or `undefined` if the Web Audio API is supported.
- *
- * @param callback callback to run if the browser does not support the Web Audio API
- */
- notSupported(callback: () => T): T | undefined;
- /**
- * Closes Crunker's internal AudioContext.
- */
- close(): this;
- /**
- * Returns the largest duration of the longest AudioBuffer.
- *
- * @internal
- */
- private _maxDuration;
- /**
- * Returns the largest number of channels in an array of AudioBuffers.
- *
- * @internal
- */
- private _maxNumberOfChannels;
- /**
- * Returns the sum of the lengths of an array of AudioBuffers.
- *
- * @internal
- */
- private _totalLength;
- /**
- * Returns whether the browser supports the Web Audio API.
- *
- * @internal
- */
- private _isSupported;
- /**
- * Writes the WAV headers for the specified Float32Array.
- *
- * Returns a DataView containing the WAV headers and file content.
- *
- * @internal
- */
- private _writeHeaders;
- /**
- * Converts a Float32Array to 16-bit PCM.
- *
- * @internal
- */
- private _floatTo16BitPCM;
- /**
- * Writes a string to a DataView at the specified offset.
- *
- * @internal
- */
- private _writeString;
- /**
- * Converts an AudioBuffer to a Float32Array.
- *
- * @internal
- */
- private _interleave;
- /**
- * Creates an HTMLAudioElement whose source is the specified Blob.
- *
- * @internal
- */
- private _renderAudioElement;
- /**
- * Creates an Object URL for the specified Blob.
- *
- * @internal
- */
- private _renderURL;
-}
+export interface CrunkerConstructorOptions {
+ /**
+ * Sample rate for Crunker's internal audio context.
+ *
+ * @default 44100
+ */
+ sampleRate: number;
+}
+export type CrunkerInputTypes = string | File | Blob;
+/**
+ * An exported Crunker audio object.
+ */
+export interface ExportedCrunkerAudio {
+ blob: Blob;
+ url: string;
+ element: HTMLAudioElement;
+}
+/**
+ * Crunker is the simple way to merge, concatenate, play, export and download audio files using the Web Audio API.
+ */
+export default class Crunker {
+ private readonly _sampleRate;
+ private readonly _context;
+ /**
+ * Creates a new instance of Crunker with the provided options.
+ *
+ * If `sampleRate` is not defined, it will auto-select an appropriate sample rate
+ * for the device being used.
+ */
+ constructor({ sampleRate }?: Partial);
+ /**
+ * Creates Crunker's internal AudioContext.
+ *
+ * @internal
+ */
+ private _createContext;
+ /**
+ *
+ * The internal AudioContext used by Crunker.
+ */
+ get context(): AudioContext;
+ /**
+ * Asynchronously fetches multiple audio files and returns an array of AudioBuffers.
+ */
+ fetchAudio(...filepaths: CrunkerInputTypes[]): Promise;
+ /**
+ * Merges (layers) multiple AudioBuffers into a single AudioBuffer.
+ *
+ * **Visual representation:**
+ *
+ * 
+ */
+ mergeAudio(buffers: AudioBuffer[]): AudioBuffer;
+ /**
+ * Concatenates multiple AudioBuffers into a single AudioBuffer.
+ *
+ * **Visual representation:**
+ *
+ * 
+ */
+ concatAudio(buffers: AudioBuffer[]): AudioBuffer;
+ /**
+ * Pads a specified AudioBuffer with silence from a specified start time,
+ * for a specified length of time.
+ *
+ * Accepts float values as well as whole integers.
+ *
+ * @param buffer AudioBuffer to pad
+ * @param padStart Time to start padding (in seconds)
+ * @param seconds Duration to pad for (in seconds)
+ */
+ padAudio(buffer: AudioBuffer, padStart?: number, seconds?: number): AudioBuffer;
+ /**
+ * Slices an AudioBuffer from the specified start time to the end time, with optional fade in and out.
+ *
+ * @param buffer AudioBuffer to slice
+ * @param start Start time (in seconds)
+ * @param end End time (in seconds)
+ * @param fadeIn Fade in duration (in seconds, default is 0)
+ * @param fadeOut Fade out duration (in seconds, default is 0)
+ */
+ sliceAudio(buffer: AudioBuffer, start: number, end: number, fadeIn?: number, fadeOut?: number): AudioBuffer;
+ /**
+ * Plays the provided AudioBuffer in an AudioBufferSourceNode.
+ */
+ play(buffer: AudioBuffer): AudioBufferSourceNode;
+ /**
+ * Exports the specified AudioBuffer to a Blob, Object URI and HTMLAudioElement.
+ *
+ * Note that changing the MIME type does not change the actual file format. The
+ * file format will **always** be a WAVE file due to how audio is stored in the
+ * browser.
+ *
+ * @param buffer Buffer to export
+ * @param type MIME type (default: `audio/wav`)
+ */
+ export(buffer: AudioBuffer, type?: string): ExportedCrunkerAudio;
+ /**
+ * Downloads the provided Blob.
+ *
+ * @param blob Blob to download
+ * @param filename An optional file name to use for the download (default: `crunker`)
+ */
+ download(blob: Blob, filename?: string): HTMLAnchorElement;
+ /**
+ * Executes a callback if the browser does not support the Web Audio API.
+ *
+ * Returns the result of the callback, or `undefined` if the Web Audio API is supported.
+ *
+ * @param callback callback to run if the browser does not support the Web Audio API
+ */
+ notSupported(callback: () => T): T | undefined;
+ /**
+ * Closes Crunker's internal AudioContext.
+ */
+ close(): this;
+ /**
+ * Returns the largest duration of the longest AudioBuffer.
+ *
+ * @internal
+ */
+ private _maxDuration;
+ /**
+ * Returns the largest number of channels in an array of AudioBuffers.
+ *
+ * @internal
+ */
+ private _maxNumberOfChannels;
+ /**
+ * Returns the sum of the lengths of an array of AudioBuffers.
+ *
+ * @internal
+ */
+ private _totalLength;
+ /**
+ * Returns whether the browser supports the Web Audio API.
+ *
+ * @internal
+ */
+ private _isSupported;
+ /**
+ * Writes the WAV headers for the specified Float32Array.
+ *
+ * Returns a DataView containing the WAV headers and file content.
+ *
+ * @internal
+ */
+ private _writeHeaders;
+ /**
+ * Converts a Float32Array to 16-bit PCM.
+ *
+ * @internal
+ */
+ private _floatTo16BitPCM;
+ /**
+ * Writes a string to a DataView at the specified offset.
+ *
+ * @internal
+ */
+ private _writeString;
+ /**
+ * Converts an AudioBuffer to a Float32Array.
+ *
+ * @internal
+ */
+ private _interleave;
+ /**
+ * Creates an HTMLAudioElement whose source is the specified Blob.
+ *
+ * @internal
+ */
+ private _renderAudioElement;
+ /**
+ * Creates an Object URL for the specified Blob.
+ *
+ * @internal
+ */
+ private _renderURL;
+}
diff --git a/system/tts_generator/crunker.esm.js b/system/tts_generator/crunker.esm.js
index a6f5633..e1086c0 100644
--- a/system/tts_generator/crunker.esm.js
+++ b/system/tts_generator/crunker.esm.js
@@ -1,2 +1,2 @@
-var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function r(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nu});var u=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.sampleRate;o(this,e),this._context=this._createContext(n),n||(n=this._context.sampleRate),this._sampleRate=n}var t,n,a;return t=e,n=[{key:"_createContext",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:44100;return window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext,new AudioContext({sampleRate:e})}},{key:"context",get:function(){return this._context}},{key:"fetchAudio",value:async function(){for(var e=this,t=arguments.length,n=new Array(t),r=0;r=0;o--)r[o]+=a[o];t.getChannelData(n).set(r)}})),t}},{key:"concatAudio",value:function(e){var t=this._context.createBuffer(this._maxNumberOfChannels(e),this._totalLength(e),this._sampleRate),n=0;return e.forEach((function(e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;if(0===n)return e;if(t<0)throw new Error('Crunker: Parameter "padStart" in padAudio must be positive');if(n<0)throw new Error('Crunker: Parameter "seconds" in padAudio must be positive');for(var r=this._context.createBuffer(e.numberOfChannels,Math.ceil(e.length+n*e.sampleRate),e.sampleRate),a=0;a3&&void 0!==arguments[3]?arguments[3]:0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;if(t>=n)throw new Error('Crunker: "start" time should be less than "end" time in sliceAudio method');for(var o=Math.round((n-t)*this._sampleRate),i=Math.round(t*this._sampleRate),u=this._context.createBuffer(e.numberOfChannels,o,this._sampleRate),l=0;lo-a*this._sampleRate&&(c[f]*=(o-f)/(a*this._sampleRate));return u}},{key:"play",value:function(e){var t=this._context.createBufferSource();return t.buffer=e,t.connect(this._context.destination),t.start(),t}},{key:"export",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"audio/wav",n=this._interleave(e),r=this._writeHeaders(n,e.numberOfChannels,e.sampleRate),a=new Blob([r],{type:t});return{blob:a,url:this._renderURL(a),element:this._renderAudioElement(a)}}},{key:"download",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"crunker",n=document.createElement("a");return n.style.display="none",n.href=this._renderURL(e),n.download="".concat(t,".").concat(e.type.split("/")[1]),n.click(),n}},{key:"notSupported",value:function(e){return this._isSupported()?void 0:e()}},{key:"close",value:function(){return this._context.close(),this}},{key:"_maxDuration",value:function(e){return Math.max.apply(Math,r(e.map((function(e){return e.duration}))))}},{key:"_maxNumberOfChannels",value:function(e){return Math.max.apply(Math,r(e.map((function(e){return e.numberOfChannels}))))}},{key:"_totalLength",value:function(e){return e.map((function(e){return e.length})).reduce((function(e,t){return e+t}),0)}},{key:"_isSupported",value:function(){return"AudioContext"in window||"webkitAudioContext"in window||"mozAudioContext"in window}},{key:"_writeHeaders",value:function(e,t,n){var r=2*t,a=2*e.length,o=36+a,i=new ArrayBuffer(8+o),u=new DataView(i);return this._writeString(u,0,"RIFF"),u.setUint32(4,o,!0),this._writeString(u,8,"WAVE"),this._writeString(u,12,"fmt "),u.setUint32(16,16,!0),u.setUint16(20,1,!0),u.setUint16(22,t,!0),u.setUint32(24,n,!0),u.setUint32(28,n*r,!0),u.setUint16(32,r,!0),u.setUint16(34,16,!0),this._writeString(u,36,"data"),u.setUint32(40,a,!0),this._floatTo16BitPCM(u,e,44)}},{key:"_floatTo16BitPCM",value:function(e,t,n){for(var r=0;r{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function r(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nu});var u=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.sampleRate;o(this,e),this._context=this._createContext(n),n||(n=this._context.sampleRate),this._sampleRate=n}var t,n,a;return t=e,n=[{key:"_createContext",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:44100;return window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext,new AudioContext({sampleRate:e})}},{key:"context",get:function(){return this._context}},{key:"fetchAudio",value:async function(){for(var e=this,t=arguments.length,n=new Array(t),r=0;r=0;o--)r[o]+=a[o];t.getChannelData(n).set(r)}})),t}},{key:"concatAudio",value:function(e){var t=this._context.createBuffer(this._maxNumberOfChannels(e),this._totalLength(e),this._sampleRate),n=0;return e.forEach((function(e){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;if(0===n)return e;if(t<0)throw new Error('Crunker: Parameter "padStart" in padAudio must be positive');if(n<0)throw new Error('Crunker: Parameter "seconds" in padAudio must be positive');for(var r=this._context.createBuffer(e.numberOfChannels,Math.ceil(e.length+n*e.sampleRate),e.sampleRate),a=0;a3&&void 0!==arguments[3]?arguments[3]:0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;if(t>=n)throw new Error('Crunker: "start" time should be less than "end" time in sliceAudio method');for(var o=Math.round((n-t)*this._sampleRate),i=Math.round(t*this._sampleRate),u=this._context.createBuffer(e.numberOfChannels,o,this._sampleRate),l=0;lo-a*this._sampleRate&&(c[f]*=(o-f)/(a*this._sampleRate));return u}},{key:"play",value:function(e){var t=this._context.createBufferSource();return t.buffer=e,t.connect(this._context.destination),t.start(),t}},{key:"export",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"audio/wav",n=this._interleave(e),r=this._writeHeaders(n,e.numberOfChannels,e.sampleRate),a=new Blob([r],{type:t});return{blob:a,url:this._renderURL(a),element:this._renderAudioElement(a)}}},{key:"download",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"crunker",n=document.createElement("a");return n.style.display="none",n.href=this._renderURL(e),n.download="".concat(t,".").concat(e.type.split("/")[1]),n.click(),n}},{key:"notSupported",value:function(e){return this._isSupported()?void 0:e()}},{key:"close",value:function(){return this._context.close(),this}},{key:"_maxDuration",value:function(e){return Math.max.apply(Math,r(e.map((function(e){return e.duration}))))}},{key:"_maxNumberOfChannels",value:function(e){return Math.max.apply(Math,r(e.map((function(e){return e.numberOfChannels}))))}},{key:"_totalLength",value:function(e){return e.map((function(e){return e.length})).reduce((function(e,t){return e+t}),0)}},{key:"_isSupported",value:function(){return"AudioContext"in window||"webkitAudioContext"in window||"mozAudioContext"in window}},{key:"_writeHeaders",value:function(e,t,n){var r=2*t,a=2*e.length,o=36+a,i=new ArrayBuffer(8+o),u=new DataView(i);return this._writeString(u,0,"RIFF"),u.setUint32(4,o,!0),this._writeString(u,8,"WAVE"),this._writeString(u,12,"fmt "),u.setUint32(16,16,!0),u.setUint16(20,1,!0),u.setUint16(22,t,!0),u.setUint32(24,n,!0),u.setUint32(28,n*r,!0),u.setUint16(32,r,!0),u.setUint16(34,16,!0),this._writeString(u,36,"data"),u.setUint32(40,a,!0),this._floatTo16BitPCM(u,e,44)}},{key:"_floatTo16BitPCM",value:function(e,t,n){for(var r=0;rEnglish
+