@ai-coustics/aic-sdk 0.6.3 → 0.12.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.
package/dist/index.d.ts DELETED
@@ -1,188 +0,0 @@
1
- /**
2
- * Node.js bindings for ai-coustics speech enhancement SDK
3
- * @packageDocumentation
4
- */
5
- /**
6
- * Error codes returned by the SDK
7
- */
8
- export declare enum ErrorCode {
9
- /** Operation completed successfully */
10
- SUCCESS = 0,
11
- /** Required pointer argument was NULL */
12
- NULL_POINTER = 1,
13
- /** License key format is invalid or corrupted */
14
- LICENSE_INVALID = 2,
15
- /** License key has expired */
16
- LICENSE_EXPIRED = 3,
17
- /** Audio configuration is not supported by the model */
18
- UNSUPPORTED_AUDIO_CONFIG = 4,
19
- /** Process was called with a different audio buffer configuration than initialized */
20
- AUDIO_CONFIG_MISMATCH = 5,
21
- /** Model must be initialized before this operation */
22
- NOT_INITIALIZED = 6,
23
- /** Parameter value is outside acceptable range */
24
- PARAMETER_OUT_OF_RANGE = 7,
25
- /** SDK activation failed */
26
- SDK_ACTIVATION_ERROR = 8
27
- }
28
- /**
29
- * Available model types for audio enhancement
30
- */
31
- export declare enum ModelType {
32
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 30ms */
33
- QUAIL_L48 = 0,
34
- /** Native sample rate: 16 kHz, Native num frames: 160, Processing latency: 30ms */
35
- QUAIL_L16 = 1,
36
- /** Native sample rate: 8 kHz, Native num frames: 80, Processing latency: 30ms */
37
- QUAIL_L8 = 2,
38
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 30ms */
39
- QUAIL_S48 = 3,
40
- /** Native sample rate: 16 kHz, Native num frames: 160, Processing latency: 30ms */
41
- QUAIL_S16 = 4,
42
- /** Native sample rate: 8 kHz, Native num frames: 80, Processing latency: 30ms */
43
- QUAIL_S8 = 5,
44
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 10ms */
45
- QUAIL_XS = 6,
46
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 10ms */
47
- QUAIL_XXS = 7
48
- }
49
- /**
50
- * Configurable parameters for audio enhancement
51
- */
52
- export declare enum Parameter {
53
- /**
54
- * Controls the intensity of speech enhancement processing.
55
- * Range: 0.0 to 1.0
56
- * - 0.0: Bypass mode - original signal passes through unchanged
57
- * - 1.0: Full enhancement - maximum noise reduction
58
- * Default: 1.0
59
- */
60
- ENHANCEMENT_LEVEL = 0,
61
- /**
62
- * Compensates for perceived volume reduction after noise removal.
63
- * Range: 0.1 to 4.0 (linear amplitude multiplier)
64
- * - 0.1: Significant volume reduction (-20 dB)
65
- * - 1.0: No gain change (0 dB, default)
66
- * - 2.0: Double amplitude (+6 dB)
67
- * - 4.0: Maximum boost (+12 dB)
68
- * Default: 1.0
69
- */
70
- VOICE_GAIN = 1,
71
- /**
72
- * Enables/disables a noise gate as a post-processing step.
73
- * Valid values: 0.0 or 1.0
74
- * - 0.0: Noise gate disabled
75
- * - 1.0: Noise gate enabled
76
- * Default: 0.0
77
- */
78
- NOISE_GATE_ENABLE = 2
79
- }
80
- /**
81
- * Configuration for model initialization
82
- */
83
- export interface AudioConfig {
84
- /** Audio sample rate in Hz (8000 - 192000) */
85
- sampleRate: number;
86
- /** Number of audio channels (1 for mono, 2 for stereo, etc.) */
87
- numChannels: number;
88
- /** Number of samples per channel in each process call */
89
- numFrames: number;
90
- }
91
- /**
92
- * High-level interface for the ai-coustics speech enhancement model
93
- */
94
- export declare class Model {
95
- private handle;
96
- private _isInitialized;
97
- /**
98
- * Creates a new audio enhancement model instance
99
- * @param modelType - The enhancement algorithm variant to use
100
- * @param licenseKey - Your license key
101
- * @throws Error if model creation fails
102
- */
103
- constructor(modelType: ModelType, licenseKey: string);
104
- /**
105
- * Configures the model for a specific audio format
106
- * Must be called before processing any audio
107
- * @param config - Audio configuration parameters
108
- * @throws Error if initialization fails
109
- */
110
- initialize(config: AudioConfig): void;
111
- /**
112
- * Clears all internal state and buffers
113
- * Call this when the audio stream is interrupted
114
- * @throws Error if reset fails
115
- */
116
- reset(): void;
117
- /**
118
- * Processes audio with interleaved channel data (in-place)
119
- * @param audio - Float32Array containing interleaved audio data
120
- * @param numChannels - Number of channels (must match initialization)
121
- * @param numFrames - Number of frames (must match initialization)
122
- * @throws Error if processing fails
123
- */
124
- processInterleaved(audio: Float32Array, numChannels: number, numFrames: number): void;
125
- /**
126
- * Processes audio with separate buffers for each channel (in-place)
127
- * Maximum of 16 channels
128
- * @param audio - Array of Float32Array, one per channel
129
- * @param numChannels - Number of channels (must match initialization)
130
- * @param numFrames - Number of frames per channel (must match initialization)
131
- * @throws Error if processing fails
132
- */
133
- processPlanar(audio: Float32Array[], numChannels: number, numFrames: number): void;
134
- /**
135
- * Sets a model parameter
136
- * @param parameter - The parameter to modify
137
- * @param value - New parameter value
138
- * @throws Error if setting parameter fails
139
- */
140
- setParameter(parameter: Parameter, value: number): void;
141
- /**
142
- * Gets the current value of a parameter
143
- * @param parameter - The parameter to query
144
- * @returns Current parameter value
145
- * @throws Error if getting parameter fails
146
- */
147
- getParameter(parameter: Parameter): number;
148
- /**
149
- * Returns the total output delay in samples for the current audio configuration
150
- * @returns Delay in samples
151
- * @throws Error if getting delay fails
152
- */
153
- getOutputDelay(): number;
154
- /**
155
- * Gets the native sample rate of the selected model
156
- * @returns Optimal sample rate in Hz
157
- * @throws Error if getting sample rate fails
158
- */
159
- getOptimalSampleRate(): number;
160
- /**
161
- * Gets the native number of frames for the selected model
162
- * @returns Optimal frame count
163
- * @throws Error if getting frame count fails
164
- */
165
- getOptimalNumFrames(): number;
166
- /**
167
- * Checks if the model has been initialized
168
- */
169
- get isInitialized(): boolean;
170
- /**
171
- * Releases all resources associated with the model
172
- */
173
- destroy(): void;
174
- private getErrorMessage;
175
- }
176
- /**
177
- * Returns the version of the SDK
178
- */
179
- export declare function getSdkVersion(): string;
180
- declare const _default: {
181
- Model: typeof Model;
182
- ModelType: typeof ModelType;
183
- Parameter: typeof Parameter;
184
- ErrorCode: typeof ErrorCode;
185
- getSdkVersion: typeof getSdkVersion;
186
- };
187
- export default _default;
188
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,oBAAY,SAAS;IACnB,uCAAuC;IACvC,OAAO,IAAI;IACX,yCAAyC;IACzC,YAAY,IAAI;IAChB,iDAAiD;IACjD,eAAe,IAAI;IACnB,8BAA8B;IAC9B,eAAe,IAAI;IACnB,wDAAwD;IACxD,wBAAwB,IAAI;IAC5B,sFAAsF;IACtF,qBAAqB,IAAI;IACzB,sDAAsD;IACtD,eAAe,IAAI;IACnB,kDAAkD;IAClD,sBAAsB,IAAI;IAC1B,4BAA4B;IAC5B,oBAAoB,IAAI;CACzB;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB,mFAAmF;IACnF,SAAS,IAAI;IACb,mFAAmF;IACnF,SAAS,IAAI;IACb,iFAAiF;IACjF,QAAQ,IAAI;IACZ,mFAAmF;IACnF,SAAS,IAAI;IACb,mFAAmF;IACnF,SAAS,IAAI;IACb,iFAAiF;IACjF,QAAQ,IAAI;IACZ,mFAAmF;IACnF,QAAQ,IAAI;IACZ,mFAAmF;IACnF,SAAS,IAAI;CACd;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB;;;;;;OAMG;IACH,iBAAiB,IAAI;IAErB;;;;;;;;OAQG;IACH,UAAU,IAAI;IAEd;;;;;;OAMG;IACH,iBAAiB,IAAI;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,cAAc,CAAkB;IAExC;;;;;OAKG;gBACS,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM;IAQpD;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAQrC;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAOb;;;;;;OAMG;IACH,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAOrF;;;;;;;OAOG;IACH,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAOlF;;;;;OAKG;IACH,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAOvD;;;;;OAKG;IACH,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM;IAQ1C;;;;OAIG;IACH,cAAc,IAAI,MAAM;IAQxB;;;;OAIG;IACH,oBAAoB,IAAI,MAAM;IAQ9B;;;;OAIG;IACH,mBAAmB,IAAI,MAAM;IAQ7B;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;OAEG;IACH,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,eAAe;CAcxB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;;;;;;;;AAGD,wBAME"}
package/dist/index.js DELETED
@@ -1,264 +0,0 @@
1
- "use strict";
2
- /**
3
- * Node.js bindings for ai-coustics speech enhancement SDK
4
- * @packageDocumentation
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Model = exports.Parameter = exports.ModelType = exports.ErrorCode = void 0;
8
- exports.getSdkVersion = getSdkVersion;
9
- // Load the native addon
10
- const binding = require('../build/Release/aic_binding.node');
11
- /**
12
- * Error codes returned by the SDK
13
- */
14
- var ErrorCode;
15
- (function (ErrorCode) {
16
- /** Operation completed successfully */
17
- ErrorCode[ErrorCode["SUCCESS"] = 0] = "SUCCESS";
18
- /** Required pointer argument was NULL */
19
- ErrorCode[ErrorCode["NULL_POINTER"] = 1] = "NULL_POINTER";
20
- /** License key format is invalid or corrupted */
21
- ErrorCode[ErrorCode["LICENSE_INVALID"] = 2] = "LICENSE_INVALID";
22
- /** License key has expired */
23
- ErrorCode[ErrorCode["LICENSE_EXPIRED"] = 3] = "LICENSE_EXPIRED";
24
- /** Audio configuration is not supported by the model */
25
- ErrorCode[ErrorCode["UNSUPPORTED_AUDIO_CONFIG"] = 4] = "UNSUPPORTED_AUDIO_CONFIG";
26
- /** Process was called with a different audio buffer configuration than initialized */
27
- ErrorCode[ErrorCode["AUDIO_CONFIG_MISMATCH"] = 5] = "AUDIO_CONFIG_MISMATCH";
28
- /** Model must be initialized before this operation */
29
- ErrorCode[ErrorCode["NOT_INITIALIZED"] = 6] = "NOT_INITIALIZED";
30
- /** Parameter value is outside acceptable range */
31
- ErrorCode[ErrorCode["PARAMETER_OUT_OF_RANGE"] = 7] = "PARAMETER_OUT_OF_RANGE";
32
- /** SDK activation failed */
33
- ErrorCode[ErrorCode["SDK_ACTIVATION_ERROR"] = 8] = "SDK_ACTIVATION_ERROR";
34
- })(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
35
- /**
36
- * Available model types for audio enhancement
37
- */
38
- var ModelType;
39
- (function (ModelType) {
40
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 30ms */
41
- ModelType[ModelType["QUAIL_L48"] = 0] = "QUAIL_L48";
42
- /** Native sample rate: 16 kHz, Native num frames: 160, Processing latency: 30ms */
43
- ModelType[ModelType["QUAIL_L16"] = 1] = "QUAIL_L16";
44
- /** Native sample rate: 8 kHz, Native num frames: 80, Processing latency: 30ms */
45
- ModelType[ModelType["QUAIL_L8"] = 2] = "QUAIL_L8";
46
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 30ms */
47
- ModelType[ModelType["QUAIL_S48"] = 3] = "QUAIL_S48";
48
- /** Native sample rate: 16 kHz, Native num frames: 160, Processing latency: 30ms */
49
- ModelType[ModelType["QUAIL_S16"] = 4] = "QUAIL_S16";
50
- /** Native sample rate: 8 kHz, Native num frames: 80, Processing latency: 30ms */
51
- ModelType[ModelType["QUAIL_S8"] = 5] = "QUAIL_S8";
52
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 10ms */
53
- ModelType[ModelType["QUAIL_XS"] = 6] = "QUAIL_XS";
54
- /** Native sample rate: 48 kHz, Native num frames: 480, Processing latency: 10ms */
55
- ModelType[ModelType["QUAIL_XXS"] = 7] = "QUAIL_XXS";
56
- })(ModelType || (exports.ModelType = ModelType = {}));
57
- /**
58
- * Configurable parameters for audio enhancement
59
- */
60
- var Parameter;
61
- (function (Parameter) {
62
- /**
63
- * Controls the intensity of speech enhancement processing.
64
- * Range: 0.0 to 1.0
65
- * - 0.0: Bypass mode - original signal passes through unchanged
66
- * - 1.0: Full enhancement - maximum noise reduction
67
- * Default: 1.0
68
- */
69
- Parameter[Parameter["ENHANCEMENT_LEVEL"] = 0] = "ENHANCEMENT_LEVEL";
70
- /**
71
- * Compensates for perceived volume reduction after noise removal.
72
- * Range: 0.1 to 4.0 (linear amplitude multiplier)
73
- * - 0.1: Significant volume reduction (-20 dB)
74
- * - 1.0: No gain change (0 dB, default)
75
- * - 2.0: Double amplitude (+6 dB)
76
- * - 4.0: Maximum boost (+12 dB)
77
- * Default: 1.0
78
- */
79
- Parameter[Parameter["VOICE_GAIN"] = 1] = "VOICE_GAIN";
80
- /**
81
- * Enables/disables a noise gate as a post-processing step.
82
- * Valid values: 0.0 or 1.0
83
- * - 0.0: Noise gate disabled
84
- * - 1.0: Noise gate enabled
85
- * Default: 0.0
86
- */
87
- Parameter[Parameter["NOISE_GATE_ENABLE"] = 2] = "NOISE_GATE_ENABLE";
88
- })(Parameter || (exports.Parameter = Parameter = {}));
89
- /**
90
- * High-level interface for the ai-coustics speech enhancement model
91
- */
92
- class Model {
93
- /**
94
- * Creates a new audio enhancement model instance
95
- * @param modelType - The enhancement algorithm variant to use
96
- * @param licenseKey - Your license key
97
- * @throws Error if model creation fails
98
- */
99
- constructor(modelType, licenseKey) {
100
- this._isInitialized = false;
101
- const result = binding.createModel(modelType, licenseKey);
102
- if (result.error !== ErrorCode.SUCCESS) {
103
- throw new Error(`Failed to create model: ${this.getErrorMessage(result.error)}`);
104
- }
105
- this.handle = result.model;
106
- }
107
- /**
108
- * Configures the model for a specific audio format
109
- * Must be called before processing any audio
110
- * @param config - Audio configuration parameters
111
- * @throws Error if initialization fails
112
- */
113
- initialize(config) {
114
- const error = binding.initialize(this.handle, config.sampleRate, config.numChannels, config.numFrames);
115
- if (error !== ErrorCode.SUCCESS) {
116
- throw new Error(`Failed to initialize model: ${this.getErrorMessage(error)}`);
117
- }
118
- this._isInitialized = true;
119
- }
120
- /**
121
- * Clears all internal state and buffers
122
- * Call this when the audio stream is interrupted
123
- * @throws Error if reset fails
124
- */
125
- reset() {
126
- const error = binding.reset(this.handle);
127
- if (error !== ErrorCode.SUCCESS) {
128
- throw new Error(`Failed to reset model: ${this.getErrorMessage(error)}`);
129
- }
130
- }
131
- /**
132
- * Processes audio with interleaved channel data (in-place)
133
- * @param audio - Float32Array containing interleaved audio data
134
- * @param numChannels - Number of channels (must match initialization)
135
- * @param numFrames - Number of frames (must match initialization)
136
- * @throws Error if processing fails
137
- */
138
- processInterleaved(audio, numChannels, numFrames) {
139
- const error = binding.processInterleaved(this.handle, audio, numChannels, numFrames);
140
- if (error !== ErrorCode.SUCCESS) {
141
- throw new Error(`Failed to process audio: ${this.getErrorMessage(error)}`);
142
- }
143
- }
144
- /**
145
- * Processes audio with separate buffers for each channel (in-place)
146
- * Maximum of 16 channels
147
- * @param audio - Array of Float32Array, one per channel
148
- * @param numChannels - Number of channels (must match initialization)
149
- * @param numFrames - Number of frames per channel (must match initialization)
150
- * @throws Error if processing fails
151
- */
152
- processPlanar(audio, numChannels, numFrames) {
153
- const error = binding.processPlanar(this.handle, audio, numChannels, numFrames);
154
- if (error !== ErrorCode.SUCCESS) {
155
- throw new Error(`Failed to process audio: ${this.getErrorMessage(error)}`);
156
- }
157
- }
158
- /**
159
- * Sets a model parameter
160
- * @param parameter - The parameter to modify
161
- * @param value - New parameter value
162
- * @throws Error if setting parameter fails
163
- */
164
- setParameter(parameter, value) {
165
- const error = binding.setParameter(this.handle, parameter, value);
166
- if (error !== ErrorCode.SUCCESS) {
167
- throw new Error(`Failed to set parameter: ${this.getErrorMessage(error)}`);
168
- }
169
- }
170
- /**
171
- * Gets the current value of a parameter
172
- * @param parameter - The parameter to query
173
- * @returns Current parameter value
174
- * @throws Error if getting parameter fails
175
- */
176
- getParameter(parameter) {
177
- const result = binding.getParameter(this.handle, parameter);
178
- if (result.error !== ErrorCode.SUCCESS) {
179
- throw new Error(`Failed to get parameter: ${this.getErrorMessage(result.error)}`);
180
- }
181
- return result.value;
182
- }
183
- /**
184
- * Returns the total output delay in samples for the current audio configuration
185
- * @returns Delay in samples
186
- * @throws Error if getting delay fails
187
- */
188
- getOutputDelay() {
189
- const result = binding.getOutputDelay(this.handle);
190
- if (result.error !== ErrorCode.SUCCESS) {
191
- throw new Error(`Failed to get output delay: ${this.getErrorMessage(result.error)}`);
192
- }
193
- return result.delay;
194
- }
195
- /**
196
- * Gets the native sample rate of the selected model
197
- * @returns Optimal sample rate in Hz
198
- * @throws Error if getting sample rate fails
199
- */
200
- getOptimalSampleRate() {
201
- const result = binding.getOptimalSampleRate(this.handle);
202
- if (result.error !== ErrorCode.SUCCESS) {
203
- throw new Error(`Failed to get optimal sample rate: ${this.getErrorMessage(result.error)}`);
204
- }
205
- return result.sampleRate;
206
- }
207
- /**
208
- * Gets the native number of frames for the selected model
209
- * @returns Optimal frame count
210
- * @throws Error if getting frame count fails
211
- */
212
- getOptimalNumFrames() {
213
- const result = binding.getOptimalNumFrames(this.handle);
214
- if (result.error !== ErrorCode.SUCCESS) {
215
- throw new Error(`Failed to get optimal num frames: ${this.getErrorMessage(result.error)}`);
216
- }
217
- return result.numFrames;
218
- }
219
- /**
220
- * Checks if the model has been initialized
221
- */
222
- get isInitialized() {
223
- return this._isInitialized;
224
- }
225
- /**
226
- * Releases all resources associated with the model
227
- */
228
- destroy() {
229
- if (this.handle) {
230
- binding.destroyModel(this.handle);
231
- this.handle = null;
232
- this._isInitialized = false;
233
- }
234
- }
235
- getErrorMessage(errorCode) {
236
- const messages = {
237
- [ErrorCode.SUCCESS]: 'Operation completed successfully',
238
- [ErrorCode.NULL_POINTER]: 'Required pointer argument was NULL',
239
- [ErrorCode.LICENSE_INVALID]: 'License key format is invalid or corrupted',
240
- [ErrorCode.LICENSE_EXPIRED]: 'License key has expired',
241
- [ErrorCode.UNSUPPORTED_AUDIO_CONFIG]: 'Audio configuration is not supported by the model',
242
- [ErrorCode.AUDIO_CONFIG_MISMATCH]: 'Process was called with a different audio buffer configuration',
243
- [ErrorCode.NOT_INITIALIZED]: 'Model must be initialized before this operation',
244
- [ErrorCode.PARAMETER_OUT_OF_RANGE]: 'Parameter value is outside acceptable range',
245
- [ErrorCode.SDK_ACTIVATION_ERROR]: 'SDK activation failed',
246
- };
247
- return messages[errorCode] || `Unknown error code: ${errorCode}`;
248
- }
249
- }
250
- exports.Model = Model;
251
- /**
252
- * Returns the version of the SDK
253
- */
254
- function getSdkVersion() {
255
- return binding.getSdkVersion();
256
- }
257
- // Export for CommonJS compatibility
258
- exports.default = {
259
- Model,
260
- ModelType,
261
- Parameter,
262
- ErrorCode,
263
- getSdkVersion,
264
- };
@@ -1,216 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const https = require("https");
4
- const fs = require("fs");
5
- const path = require("path");
6
- const crypto = require("crypto");
7
- const { pipeline } = require("stream");
8
- const { promisify } = require("util");
9
- const tar = require("tar");
10
- const { exec } = require("child_process");
11
-
12
- const pipelineAsync = promisify(pipeline);
13
- const execAsync = promisify(exec);
14
-
15
- const SDK_VERSION = "0.6.3";
16
- const SDK_BASE_URL = `https://github.com/ai-coustics/aic-sdk-c/releases/download/${SDK_VERSION}`;
17
-
18
- // Platform-specific archive filenames
19
- const PLATFORM_MAP = {
20
- "darwin-x64": `aic-sdk-x86_64-apple-darwin-${SDK_VERSION}.tar.gz`,
21
- "darwin-arm64": `aic-sdk-aarch64-apple-darwin-${SDK_VERSION}.tar.gz`,
22
- "linux-x64": `aic-sdk-x86_64-unknown-linux-gnu-${SDK_VERSION}.tar.gz`,
23
- "linux-arm64": `aic-sdk-aarch64-unknown-linux-gnu-${SDK_VERSION}.tar.gz`,
24
- "win32-x64": `aic-sdk-x86_64-pc-windows-msvc-${SDK_VERSION}.zip`,
25
- };
26
-
27
- // SHA-256 hashes for each platform archive
28
- const PLATFORM_HASHES = {
29
- "darwin-x64":
30
- "a1e8050c8b87b645c2acb5bce396aa964640074b183da54248c2ef9549c41b6b",
31
- "darwin-arm64":
32
- "35384d0e51733f39276c427a92f13d4a983404634604ec5fbeda10a3debc2860",
33
- "linux-x64":
34
- "e22593f5cc6241be3d495d4a154c1157f298213e614cbe248a419745fc02e681",
35
- "linux-arm64":
36
- "3c10d6af456d8d6641f7e0f82e85145f79d7b1b6459c820e489f685296fafc28",
37
- "win32-x64":
38
- "c6a414e23285e3c2930cae4c942f02aea30175a2986a2871304e6229b83bc91b",
39
- };
40
-
41
- function getPlatformIdentifier() {
42
- const platform = process.platform;
43
- const arch = process.arch;
44
- return `${platform}-${arch}`;
45
- }
46
-
47
- function getDownloadUrl() {
48
- const platformId = getPlatformIdentifier();
49
- const filename = PLATFORM_MAP[platformId];
50
-
51
- if (!filename) {
52
- throw new Error(
53
- `Unsupported platform: ${platformId}. Supported platforms: ${Object.keys(PLATFORM_MAP).join(", ")}`,
54
- );
55
- }
56
-
57
- return `${SDK_BASE_URL}/${filename}`;
58
- }
59
-
60
- function calculateSHA256(filePath) {
61
- return new Promise((resolve, reject) => {
62
- const hash = crypto.createHash("sha256");
63
- const stream = fs.createReadStream(filePath);
64
-
65
- stream.on("data", (data) => hash.update(data));
66
- stream.on("end", () => resolve(hash.digest("hex")));
67
- stream.on("error", reject);
68
- });
69
- }
70
-
71
- function verifyHash(filePath, expectedHash) {
72
- return calculateSHA256(filePath).then((actualHash) => {
73
- if (actualHash !== expectedHash) {
74
- throw new Error(
75
- `Hash verification failed!\nExpected: ${expectedHash}\nActual: ${actualHash}`,
76
- );
77
- }
78
- console.log("Hash verification successful!");
79
- });
80
- }
81
-
82
- function downloadFile(url, destPath) {
83
- return new Promise((resolve, reject) => {
84
- console.log(`Downloading SDK from ${url}...`);
85
-
86
- https
87
- .get(url, (response) => {
88
- if (response.statusCode === 302 || response.statusCode === 301) {
89
- // Follow redirect
90
- return downloadFile(response.headers.location, destPath)
91
- .then(resolve)
92
- .catch(reject);
93
- }
94
-
95
- if (response.statusCode !== 200) {
96
- reject(
97
- new Error(
98
- `Failed to download: ${response.statusCode} ${response.statusMessage}`,
99
- ),
100
- );
101
- return;
102
- }
103
-
104
- const fileStream = fs.createWriteStream(destPath);
105
- let downloadedBytes = 0;
106
- const totalBytes = parseInt(response.headers["content-length"], 10);
107
-
108
- response.on("data", (chunk) => {
109
- downloadedBytes += chunk.length;
110
- const progress = ((downloadedBytes / totalBytes) * 100).toFixed(1);
111
- process.stdout.write(`\rDownloading: ${progress}%`);
112
- });
113
-
114
- response.pipe(fileStream);
115
-
116
- fileStream.on("finish", () => {
117
- fileStream.close();
118
- console.log("\nDownload completed!");
119
- resolve();
120
- });
121
-
122
- fileStream.on("error", (err) => {
123
- fs.unlinkSync(destPath);
124
- reject(err);
125
- });
126
- })
127
- .on("error", reject);
128
- });
129
- }
130
-
131
- async function extractArchive(archivePath, destDir) {
132
- console.log("Extracting SDK...");
133
-
134
- const ext = path.extname(archivePath);
135
-
136
- if (ext === ".gz") {
137
- // Extract tar.gz
138
- await tar.x({
139
- file: archivePath,
140
- cwd: destDir,
141
- });
142
- } else if (ext === ".zip") {
143
- // Extract zip (Windows)
144
- const unzipper = require("child_process").spawn("powershell.exe", [
145
- "-Command",
146
- `Expand-Archive -Path "${archivePath}" -DestinationPath "${destDir}" -Force`,
147
- ]);
148
-
149
- await new Promise((resolve, reject) => {
150
- unzipper.on("close", (code) => {
151
- if (code === 0) resolve();
152
- else reject(new Error(`Extraction failed with code ${code}`));
153
- });
154
- });
155
- }
156
-
157
- console.log("Extraction completed!");
158
- }
159
-
160
- async function main() {
161
- try {
162
- const rootDir = path.join(__dirname, "..");
163
- const sdkDir = path.join(rootDir, "sdk");
164
- const tmpDir = path.join(rootDir, "tmp");
165
-
166
- // Create directories
167
- if (!fs.existsSync(tmpDir)) {
168
- fs.mkdirSync(tmpDir, { recursive: true });
169
- }
170
-
171
- // Check if SDK already exists
172
- if (fs.existsSync(sdkDir)) {
173
- console.log("SDK already downloaded. Skipping download.");
174
- return;
175
- }
176
-
177
- const downloadUrl = getDownloadUrl();
178
- const filename = path.basename(downloadUrl);
179
- const archivePath = path.join(tmpDir, filename);
180
-
181
- // Download SDK
182
- await downloadFile(downloadUrl, archivePath);
183
-
184
- // Verify the downloaded file's hash
185
- const platformId = getPlatformIdentifier();
186
- const expectedHash = PLATFORM_HASHES[platformId];
187
- console.log("Verifying download integrity...");
188
- await verifyHash(archivePath, expectedHash);
189
-
190
- // Create sdk directory for extraction
191
- fs.mkdirSync(sdkDir, { recursive: true });
192
-
193
- // Extract SDK directly into sdk directory
194
- await extractArchive(archivePath, sdkDir);
195
-
196
- // Remove unnecessary directories
197
- const unnecessaryDirs = ["examples", "docs"];
198
- for (const dir of unnecessaryDirs) {
199
- const dirPath = path.join(sdkDir, dir);
200
- if (fs.existsSync(dirPath)) {
201
- fs.rmSync(dirPath, { recursive: true, force: true });
202
- }
203
- }
204
-
205
- // Clean up
206
- fs.unlinkSync(archivePath);
207
- fs.rmdirSync(tmpDir);
208
-
209
- console.log("SDK installation completed successfully!");
210
- } catch (error) {
211
- console.error("Failed to download SDK:", error.message);
212
- process.exit(1);
213
- }
214
- }
215
-
216
- main();