@siteed/expo-audio-stream 1.0.2 → 1.0.3
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/.size-limit.json +6 -0
- package/build/AudioAnalysis/AudioAnalysis.types.d.ts +76 -0
- package/build/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -0
- package/build/AudioAnalysis/AudioAnalysis.types.js +3 -0
- package/build/AudioAnalysis/AudioAnalysis.types.js.map +1 -0
- package/build/AudioAnalysis/extractAudioAnalysis.d.ts +4 -0
- package/build/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -0
- package/build/AudioAnalysis/extractAudioAnalysis.js +101 -0
- package/build/AudioAnalysis/extractAudioAnalysis.js.map +1 -0
- package/build/AudioAnalysis/extractWaveform.d.ts +8 -0
- package/build/AudioAnalysis/extractWaveform.d.ts.map +1 -0
- package/build/AudioAnalysis/extractWaveform.js +14 -0
- package/build/AudioAnalysis/extractWaveform.js.map +1 -0
- package/build/AudioRecorder.provider.d.ts +14 -1
- package/build/AudioRecorder.provider.d.ts.map +1 -1
- package/build/AudioRecorder.provider.js +17 -4
- package/build/AudioRecorder.provider.js.map +1 -1
- package/build/ExpoAudioStream.types.d.ts +26 -84
- package/build/ExpoAudioStream.types.d.ts.map +1 -1
- package/build/ExpoAudioStream.types.js.map +1 -1
- package/build/ExpoAudioStream.web.d.ts +6 -5
- package/build/ExpoAudioStream.web.d.ts.map +1 -1
- package/build/ExpoAudioStream.web.js +9 -8
- package/build/ExpoAudioStream.web.js.map +1 -1
- package/build/ExpoAudioStreamModule.d.ts.map +1 -1
- package/build/ExpoAudioStreamModule.js +5 -1
- package/build/ExpoAudioStreamModule.js.map +1 -1
- package/build/{WebRecorder.d.ts → WebRecorder.web.d.ts} +7 -3
- package/build/WebRecorder.web.d.ts.map +1 -0
- package/build/{WebRecorder.js → WebRecorder.web.js} +74 -29
- package/build/WebRecorder.web.js.map +1 -0
- package/build/constants.d.ts +11 -0
- package/build/constants.d.ts.map +1 -0
- package/build/constants.js +14 -0
- package/build/constants.js.map +1 -0
- package/build/events.d.ts +6 -0
- package/build/events.d.ts.map +1 -0
- package/build/events.js +15 -0
- package/build/events.js.map +1 -0
- package/build/index.d.ts +8 -16
- package/build/index.d.ts.map +1 -1
- package/build/index.js +6 -112
- package/build/index.js.map +1 -1
- package/build/logger.d.ts +9 -0
- package/build/logger.d.ts.map +1 -0
- package/build/logger.js +17 -0
- package/build/logger.js.map +1 -0
- package/build/{useAudioRecording.d.ts → useAudioRecorder.d.ts} +6 -7
- package/build/useAudioRecorder.d.ts.map +1 -0
- package/build/{useAudioRecording.js → useAudioRecorder.js} +69 -65
- package/build/useAudioRecorder.js.map +1 -0
- package/build/utils/convertPCMToFloat32.d.ts +11 -0
- package/build/utils/convertPCMToFloat32.d.ts.map +1 -0
- package/build/utils/convertPCMToFloat32.js +41 -0
- package/build/utils/convertPCMToFloat32.js.map +1 -0
- package/build/utils/encodingToBitDepth.d.ts +5 -0
- package/build/utils/encodingToBitDepth.d.ts.map +1 -0
- package/build/utils/encodingToBitDepth.js +13 -0
- package/build/utils/encodingToBitDepth.js.map +1 -0
- package/build/utils/getWavFileInfo.d.ts +25 -0
- package/build/utils/getWavFileInfo.d.ts.map +1 -0
- package/build/utils/getWavFileInfo.js +89 -0
- package/build/utils/getWavFileInfo.js.map +1 -0
- package/build/utils/writeWavHeader.d.ts +9 -0
- package/build/utils/writeWavHeader.d.ts.map +1 -0
- package/build/utils/writeWavHeader.js +41 -0
- package/build/utils/writeWavHeader.js.map +1 -0
- package/build/workers/InlineFeaturesExtractor.web.d.ts +2 -0
- package/build/workers/InlineFeaturesExtractor.web.d.ts.map +1 -0
- package/build/workers/InlineFeaturesExtractor.web.js +303 -0
- package/build/workers/InlineFeaturesExtractor.web.js.map +1 -0
- package/build/workers/inlineAudioWebWorker.web.d.ts +2 -0
- package/build/workers/inlineAudioWebWorker.web.d.ts.map +1 -0
- package/build/workers/inlineAudioWebWorker.web.js +243 -0
- package/build/workers/inlineAudioWebWorker.web.js.map +1 -0
- package/ios/AudioStreamManager.swift +39 -2
- package/ios/ExpoAudioStreamModule.swift +10 -0
- package/package.json +7 -6
- package/plugin/tsconfig.json +1 -1
- package/publish.sh +0 -0
- package/src/AudioAnalysis/AudioAnalysis.types.ts +85 -0
- package/src/AudioAnalysis/extractAudioAnalysis.ts +136 -0
- package/src/AudioAnalysis/extractWaveform.ts +25 -0
- package/src/AudioRecorder.provider.tsx +35 -7
- package/src/ExpoAudioStream.types.ts +33 -94
- package/src/ExpoAudioStream.web.ts +17 -16
- package/src/ExpoAudioStreamModule.ts +6 -1
- package/src/{WebRecorder.ts → WebRecorder.web.ts} +85 -33
- package/src/constants.ts +18 -0
- package/src/events.ts +25 -0
- package/src/index.ts +8 -169
- package/src/logger.ts +26 -0
- package/src/{useAudioRecording.tsx → useAudioRecorder.tsx} +141 -136
- package/src/utils/convertPCMToFloat32.ts +48 -0
- package/src/utils/encodingToBitDepth.ts +18 -0
- package/src/utils/getWavFileInfo.ts +125 -0
- package/src/utils/writeWavHeader.ts +56 -0
- package/src/workers/InlineFeaturesExtractor.web.tsx +302 -0
- package/src/workers/inlineAudioWebWorker.web.tsx +242 -0
- package/build/WebRecorder.d.ts.map +0 -1
- package/build/WebRecorder.js.map +0 -1
- package/build/inlineAudioWebWorker.d.ts +0 -3
- package/build/inlineAudioWebWorker.d.ts.map +0 -1
- package/build/inlineAudioWebWorker.js +0 -340
- package/build/inlineAudioWebWorker.js.map +0 -1
- package/build/useAudioRecording.d.ts.map +0 -1
- package/build/useAudioRecording.js.map +0 -1
- package/build/utils.d.ts +0 -31
- package/build/utils.d.ts.map +0 -1
- package/build/utils.js +0 -143
- package/build/utils.js.map +0 -1
- package/src/inlineAudioWebWorker.tsx +0 -340
- package/src/utils.ts +0 -189
package/src/utils.ts
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { EncodingType } from "./ExpoAudioStream.types";
|
|
2
|
-
|
|
3
|
-
export const WAV_HEADER_SIZE = 44;
|
|
4
|
-
export const convertPCMToFloat32 = ({
|
|
5
|
-
bitDepth,
|
|
6
|
-
buffer,
|
|
7
|
-
skipWavHeader = false,
|
|
8
|
-
}: {
|
|
9
|
-
buffer: ArrayBuffer;
|
|
10
|
-
bitDepth: number;
|
|
11
|
-
skipWavHeader?: boolean;
|
|
12
|
-
}): { pcmValues: Float32Array; min: number; max: number } => {
|
|
13
|
-
const dataView = new DataView(buffer);
|
|
14
|
-
const headerOffset = skipWavHeader ? WAV_HEADER_SIZE : 0;
|
|
15
|
-
const dataLength = buffer.byteLength - headerOffset;
|
|
16
|
-
const sampleLength = dataLength / (bitDepth / 8);
|
|
17
|
-
const float32Array = new Float32Array(sampleLength);
|
|
18
|
-
let min = Infinity;
|
|
19
|
-
let max = -Infinity;
|
|
20
|
-
|
|
21
|
-
for (let i = 0; i < sampleLength; i++) {
|
|
22
|
-
let value = 0;
|
|
23
|
-
const offset = headerOffset + i * (bitDepth / 8);
|
|
24
|
-
switch (bitDepth) {
|
|
25
|
-
case 8:
|
|
26
|
-
value = dataView.getUint8(offset) / 128;
|
|
27
|
-
break;
|
|
28
|
-
case 16:
|
|
29
|
-
value = dataView.getInt16(offset, true) / 32768;
|
|
30
|
-
break;
|
|
31
|
-
case 24:
|
|
32
|
-
value =
|
|
33
|
-
(dataView.getUint8(offset) +
|
|
34
|
-
(dataView.getUint8(offset + 1) << 8) +
|
|
35
|
-
(dataView.getUint8(offset + 2) << 16)) /
|
|
36
|
-
8388608;
|
|
37
|
-
break;
|
|
38
|
-
case 32:
|
|
39
|
-
value = dataView.getFloat32(offset, true);
|
|
40
|
-
break;
|
|
41
|
-
default:
|
|
42
|
-
throw new Error(`Unsupported bit depth: ${bitDepth}`);
|
|
43
|
-
}
|
|
44
|
-
if (value < min) min = value;
|
|
45
|
-
if (value > max) max = value;
|
|
46
|
-
float32Array[i] = value;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return { pcmValues: float32Array, min, max };
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
interface WavHeaderOptions {
|
|
53
|
-
buffer: ArrayBuffer;
|
|
54
|
-
sampleRate: number;
|
|
55
|
-
numChannels: number;
|
|
56
|
-
bitDepth: number;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const writeWavHeader = ({
|
|
60
|
-
buffer,
|
|
61
|
-
sampleRate,
|
|
62
|
-
numChannels,
|
|
63
|
-
bitDepth,
|
|
64
|
-
}: WavHeaderOptions): ArrayBuffer => {
|
|
65
|
-
const bytesPerSample = bitDepth / 8;
|
|
66
|
-
const numSamples = buffer.byteLength / (numChannels * bytesPerSample);
|
|
67
|
-
const view = new DataView(buffer);
|
|
68
|
-
const blockAlign = numChannels * bytesPerSample;
|
|
69
|
-
const byteRate = sampleRate * blockAlign;
|
|
70
|
-
|
|
71
|
-
// Function to write a string to the DataView
|
|
72
|
-
const writeString = (view: DataView, offset: number, string: string) => {
|
|
73
|
-
for (let i = 0; i < string.length; i++) {
|
|
74
|
-
view.setUint8(offset + i, string.charCodeAt(i));
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// Check if the buffer already has a WAV header by looking for "RIFF" at the start
|
|
79
|
-
const existingHeader = view.getUint32(0, false) === 0x52494646; // "RIFF" in ASCII
|
|
80
|
-
|
|
81
|
-
if (!existingHeader) {
|
|
82
|
-
// Write the WAV header
|
|
83
|
-
writeString(view, 0, "RIFF"); // ChunkID
|
|
84
|
-
view.setUint32(4, 36 + numSamples * blockAlign, true); // ChunkSize
|
|
85
|
-
writeString(view, 8, "WAVE"); // Format
|
|
86
|
-
writeString(view, 12, "fmt "); // Subchunk1ID
|
|
87
|
-
view.setUint32(16, 16, true); // Subchunk1Size (16 for PCM)
|
|
88
|
-
view.setUint16(20, bitDepth === 32 ? 3 : 1, true); // AudioFormat (3 for float, 1 for PCM)
|
|
89
|
-
view.setUint16(22, numChannels, true); // NumChannels
|
|
90
|
-
view.setUint32(24, sampleRate, true); // SampleRate
|
|
91
|
-
view.setUint32(28, byteRate, true); // ByteRate
|
|
92
|
-
view.setUint16(32, blockAlign, true); // BlockAlign
|
|
93
|
-
view.setUint16(34, bitDepth, true); // BitsPerSample
|
|
94
|
-
writeString(view, 36, "data"); // Subchunk2ID
|
|
95
|
-
view.setUint32(40, numSamples * blockAlign, true); // Subchunk2Size
|
|
96
|
-
} else {
|
|
97
|
-
// Update the existing WAV header if necessary
|
|
98
|
-
view.setUint32(4, 36 + numSamples * blockAlign, true); // Update ChunkSize
|
|
99
|
-
view.setUint32(24, sampleRate, true); // Update SampleRate
|
|
100
|
-
view.setUint32(28, byteRate, true); // Update ByteRate
|
|
101
|
-
view.setUint16(32, blockAlign, true); // Update BlockAlign
|
|
102
|
-
view.setUint32(40, numSamples * blockAlign, true); // Update Subchunk2Size
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return buffer;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export interface WavFileInfo {
|
|
109
|
-
sampleRate: number;
|
|
110
|
-
numChannels: number;
|
|
111
|
-
bitDepth: number;
|
|
112
|
-
size: number; // in bytes
|
|
113
|
-
durationMs: number; // in seconds
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export const getWavFileInfo = async (
|
|
117
|
-
arrayBuffer: ArrayBuffer,
|
|
118
|
-
): Promise<WavFileInfo> => {
|
|
119
|
-
const view = new DataView(arrayBuffer);
|
|
120
|
-
|
|
121
|
-
// Check if the file is a valid RIFF/WAVE file
|
|
122
|
-
const riffHeader = view.getUint32(0, false); // "RIFF"
|
|
123
|
-
const waveHeader = view.getUint32(8, false); // "WAVE"
|
|
124
|
-
if (riffHeader !== 0x52494646 || waveHeader !== 0x57415645) {
|
|
125
|
-
throw new Error("Invalid WAV file");
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Locate the "fmt " chunk
|
|
129
|
-
let fmtChunkOffset = 12;
|
|
130
|
-
let sampleRate = 0;
|
|
131
|
-
let numChannels = 0;
|
|
132
|
-
let bitDepth = 0;
|
|
133
|
-
let dataChunkSize = 0;
|
|
134
|
-
let audioFormat = 0;
|
|
135
|
-
|
|
136
|
-
while (fmtChunkOffset < view.byteLength) {
|
|
137
|
-
const chunkId = view.getUint32(fmtChunkOffset, false);
|
|
138
|
-
const chunkSize = view.getUint32(fmtChunkOffset + 4, true);
|
|
139
|
-
if (chunkId === 0x666d7420) {
|
|
140
|
-
// "fmt "
|
|
141
|
-
audioFormat = view.getUint16(fmtChunkOffset + 8, true);
|
|
142
|
-
if (audioFormat !== 1 && audioFormat !== 3) {
|
|
143
|
-
throw new Error("Unsupported WAV file format");
|
|
144
|
-
}
|
|
145
|
-
numChannels = view.getUint16(fmtChunkOffset + 10, true);
|
|
146
|
-
sampleRate = view.getUint32(fmtChunkOffset + 12, true);
|
|
147
|
-
bitDepth = view.getUint16(fmtChunkOffset + 22, true);
|
|
148
|
-
} else if (chunkId === 0x64617461) {
|
|
149
|
-
// "data"
|
|
150
|
-
dataChunkSize = chunkSize;
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
fmtChunkOffset += 8 + chunkSize;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (!sampleRate || !numChannels || !bitDepth || !dataChunkSize) {
|
|
157
|
-
throw new Error("Incomplete WAV file information");
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Calculate duration
|
|
161
|
-
const bytesPerSample = bitDepth / 8;
|
|
162
|
-
const numSamples = dataChunkSize / (numChannels * bytesPerSample);
|
|
163
|
-
const durationMs = (numSamples / sampleRate) * 1000;
|
|
164
|
-
|
|
165
|
-
return {
|
|
166
|
-
sampleRate,
|
|
167
|
-
numChannels,
|
|
168
|
-
bitDepth,
|
|
169
|
-
size: arrayBuffer.byteLength,
|
|
170
|
-
durationMs,
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
export const encodingToBitDepth = ({
|
|
175
|
-
encoding,
|
|
176
|
-
}: {
|
|
177
|
-
encoding: EncodingType;
|
|
178
|
-
}): number => {
|
|
179
|
-
switch (encoding) {
|
|
180
|
-
case "pcm_32bit":
|
|
181
|
-
return 32;
|
|
182
|
-
case "pcm_16bit":
|
|
183
|
-
return 16;
|
|
184
|
-
case "pcm_8bit":
|
|
185
|
-
return 8;
|
|
186
|
-
default:
|
|
187
|
-
throw new Error(`Unsupported encoding type: ${encoding}`);
|
|
188
|
-
}
|
|
189
|
-
};
|