@qvac/decoder-audio 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,64 @@
1
+ const { QvacErrorDecoderAudio, ERR_CODES } = require('./error')
2
+
3
+ const TARGET_SECONDS = 1 // Desired chunk size in seconds
4
+ const SAMPLE_RATE = 16000 // PCM audio sample rate
5
+ const BYTES_PER_SAMPLE = 4 // PCM S16LE (16-bit)
6
+ const TARGET_BUFFER_SIZE = TARGET_SECONDS * SAMPLE_RATE * BYTES_PER_SAMPLE
7
+
8
+ /**
9
+ * Creates a stream accumulator that processes incoming audio data in chunks of a specified size.
10
+ * The accumulator maintains a buffer of incoming data and emits chunks when the target size is reached.
11
+ *
12
+ * @param {Object} options - Configuration options for the stream accumulator
13
+ * @param {Function} options.onChunk - Callback function called when a chunk of data is ready to be processed
14
+ * @param {Function} options.onFinish - Callback function called when all data has been processed
15
+ * @param {number} [options.targetBufferSize=TARGET_BUFFER_SIZE] - Target size for each chunk in bytes
16
+ * @returns {Object} An object with methods to process data and finish the stream
17
+ * @throws {Error} If the target buffer size is smaller than the minimum required size
18
+ */
19
+ function createStreamAccumulator ({
20
+ onChunk,
21
+ onFinish,
22
+ targetBufferSize = TARGET_BUFFER_SIZE
23
+ }) {
24
+ if (targetBufferSize < TARGET_BUFFER_SIZE) {
25
+ throw new QvacErrorDecoderAudio(ERR_CODES.BUFFER_SIZE_TOO_SMALL)
26
+ }
27
+
28
+ let accumulator = Buffer.alloc(0)
29
+
30
+ return {
31
+ /**
32
+ * Process incoming data and emit chunks when target size is reached.
33
+ * Accumulates incoming data until it reaches the target buffer size,
34
+ * then emits a chunk and continues with the remaining data.
35
+ *
36
+ * @param {Buffer} data - The incoming data to process
37
+ * @returns {Promise<void>} A promise that resolves when the chunk is processed
38
+ */
39
+ async processData (data) {
40
+ accumulator = Buffer.concat([accumulator, data])
41
+
42
+ while (accumulator.length >= targetBufferSize) {
43
+ const chunk = accumulator.subarray(0, targetBufferSize)
44
+ await onChunk(new Uint8Array(chunk))
45
+ accumulator = accumulator.subarray(targetBufferSize)
46
+ }
47
+ },
48
+
49
+ /**
50
+ * Finish processing and emit any remaining data.
51
+ * Processes any remaining data in the accumulator and calls the finish callback.
52
+ *
53
+ * @returns {Promise<void>} A promise that resolves when all remaining data is processed
54
+ */
55
+ async finish () {
56
+ if (accumulator.length > 0) {
57
+ await onChunk(new Uint8Array(accumulator))
58
+ }
59
+ await onFinish()
60
+ }
61
+ }
62
+ }
63
+
64
+ module.exports = createStreamAccumulator
package/utils/error.js ADDED
@@ -0,0 +1,61 @@
1
+ 'use strict'
2
+
3
+ const { QvacErrorBase, addCodes } = require('@qvac/error')
4
+ const { name, version } = require('../package.json')
5
+
6
+ class QvacErrorDecoderAudio extends QvacErrorBase { }
7
+
8
+ // This library has error code range from 11,001 to 12,000
9
+ const ERR_CODES = Object.freeze({
10
+ FAILED_TO_LOAD_WEIGHTS: 11001,
11
+ FAILED_TO_ACTIVATE: 11002,
12
+ FAILED_TO_PAUSE: 11003,
13
+ FAILED_TO_CANCEL: 11004,
14
+ FAILED_TO_APPEND: 11005,
15
+ FAILED_TO_GET_STATUS: 11006,
16
+ FAILED_TO_DESTROY: 11007,
17
+ BUFFER_SIZE_TOO_SMALL: 11008
18
+ })
19
+
20
+ addCodes({
21
+ [ERR_CODES.FAILED_TO_LOAD_WEIGHTS]: {
22
+ name: 'FAILED_TO_LOAD_WEIGHTS',
23
+ message: (message) => `Failed to load weights, error: ${message}`
24
+ },
25
+ [ERR_CODES.FAILED_TO_ACTIVATE]: {
26
+ name: 'FAILED_TO_ACTIVATE',
27
+ message: (message) => `Failed to activate model, error: ${message}`
28
+ },
29
+ [ERR_CODES.FAILED_TO_PAUSE]: {
30
+ name: 'FAILED_TO_PAUSE',
31
+ message: (message) => `Failed to pause inference, error: ${message}`
32
+ },
33
+ [ERR_CODES.FAILED_TO_CANCEL]: {
34
+ name: 'FAILED_TO_CANCEL',
35
+ message: (message) => `Failed to cancel inference, error: ${message}`
36
+ },
37
+ [ERR_CODES.FAILED_TO_APPEND]: {
38
+ name: 'FAILED_TO_APPEND',
39
+ message: (message) => `Failed to append data to processing queue, error: ${message}`
40
+ },
41
+ [ERR_CODES.FAILED_TO_GET_STATUS]: {
42
+ name: 'FAILED_TO_GET_STATUS',
43
+ message: (message) => `Failed to get addon status, error: ${message}`
44
+ },
45
+ [ERR_CODES.FAILED_TO_DESTROY]: {
46
+ name: 'FAILED_TO_DESTROY',
47
+ message: (message) => `Failed to destroy instance, error: ${message}`
48
+ },
49
+ [ERR_CODES.BUFFER_SIZE_TOO_SMALL]: {
50
+ name: 'BUFFER_SIZE_TOO_SMALL',
51
+ message: 'Target buffer size is too small'
52
+ }
53
+ }, {
54
+ name,
55
+ version
56
+ })
57
+
58
+ module.exports = {
59
+ ERR_CODES,
60
+ QvacErrorDecoderAudio
61
+ }