Skip to content

Commit

Permalink
Add function to encode samples into blob
Browse files Browse the repository at this point in the history
  • Loading branch information
hedgecrw committed Sep 17, 2024
1 parent a1169bf commit d595a33
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 29 deletions.
12 changes: 6 additions & 6 deletions library/webaudioapi/encoders/WebmOpusEncoder.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export class WebmOpusEncoder extends EncoderBase {
for (let ch = 0; ch < audioData.numberOfChannels; ++ch)
audioInputDataFloats.set(audioData.getChannelData(ch), ch * audioData.length);
const audioInput = new AudioData({ format: 'f32-planar',
sampleRate: audioData.sampleRate,
numberOfFrames: audioData.length,
numberOfChannels: audioData.numberOfChannels,
timestamp: 0,
data: audioInputData,
transfer: [audioInputData] });
sampleRate: audioData.sampleRate,
numberOfFrames: audioData.length,
numberOfChannels: audioData.numberOfChannels,
timestamp: 0,
data: audioInputData,
transfer: [audioInputData] });
const bitRate = (encodingOptions && ('bitRate' in encodingOptions)) ? encodingOptions.bitRate : 96000;
const audioEncoder = new AudioEncoder({ output: (chunk, meta) => webmMuxer.addAudioChunk(chunk, meta), error: e => console.error(e) });
audioEncoder.configure({ codec: 'opus', sampleRate: audioData.sampleRate, numberOfChannels: 1, bitrate: bitRate });
Expand Down
44 changes: 22 additions & 22 deletions library/webaudioapi/modules/Constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,34 @@
*/
export const Note = { Rest: 0,
C0: 12, C0n: -12, D0bb: 12, C0s: 13, D0b: 13, D0: 14, D0n: -14, C0ss: 14, E0bb: 14,
D0s: 15, E0b: 15, F0bb: 15, E0: 16, E0n: -16, D0ss: 16, F0b: 16, F0: 17, F0n: -17, E0s: 17, G0bb: 17,
D0s: 15, E0b: 15, F0bb: 15, E0: 16, E0n: -16, D0ss: 16, F0b: 16, F0: 17, F0n: -17, E0s: 17, G0bb: 17,
F0s: 18, E0ss: 18, G0b: 18, G0: 19, G0n: -19, F0ss: 19, A0bb: 19, G0s: 20, A0b: 20,
A0: 21, A0n: -21, G0ss: 21, B0bb: 21, A0s: 22, B0b: 22, C1bb: 22, B0: 23, B0n: -23, A0ss: 23, C1b: 23,
C1: 24, C1n: -24, B0s: 24, D1bb: 24, C1s: 25, B0ss: 25, D1b: 25, D1: 26, D1n: -26, C1ss: 26, E1bb: 26,
D1s: 27, E1b: 27, F1bb: 27, E1: 28, E1n: -28, D1ss: 28, F1b: 28, F1: 29, F1n: -29, E1s: 29, G1bb: 29,
A0: 21, A0n: -21, G0ss: 21, B0bb: 21, A0s: 22, B0b: 22, C1bb: 22, B0: 23, B0n: -23, A0ss: 23, C1b: 23,
C1: 24, C1n: -24, B0s: 24, D1bb: 24, C1s: 25, B0ss: 25, D1b: 25, D1: 26, D1n: -26, C1ss: 26, E1bb: 26,
D1s: 27, E1b: 27, F1bb: 27, E1: 28, E1n: -28, D1ss: 28, F1b: 28, F1: 29, F1n: -29, E1s: 29, G1bb: 29,
F1s: 30, E1ss: 30, G1b: 30, G1: 31, G1n: -31, F1ss: 31, A1bb: 31, G1s: 32, A1b: 32,
A1: 33, A1n: -33, G1ss: 33, B1bb: 33, A1s: 34, B1b: 34, C2bb: 34, B1: 35, B1n: -35, A1ss: 35, C2b: 35,
C2: 36, C2n: -36, B1s: 36, D2bb: 36, C2s: 37, B1ss: 37, D2b: 37, D2: 38, D2n: -38, C2ss: 38, E2bb: 38,
D2s: 39, E2b: 39, F2bb: 39, E2: 40, E2n: -40, D2ss: 40, F2b: 40, F2: 41, F2n: -41, E2s: 41, G2bb: 41,
A1: 33, A1n: -33, G1ss: 33, B1bb: 33, A1s: 34, B1b: 34, C2bb: 34, B1: 35, B1n: -35, A1ss: 35, C2b: 35,
C2: 36, C2n: -36, B1s: 36, D2bb: 36, C2s: 37, B1ss: 37, D2b: 37, D2: 38, D2n: -38, C2ss: 38, E2bb: 38,
D2s: 39, E2b: 39, F2bb: 39, E2: 40, E2n: -40, D2ss: 40, F2b: 40, F2: 41, F2n: -41, E2s: 41, G2bb: 41,
F2s: 42, E2ss: 42, G2b: 42, G2: 43, G2n: -43, F2ss: 43, A2bb: 43, G2s: 44, A2b: 44,
A2: 45, A2n: -45, G2ss: 45, B2bb: 45, A2s: 46, B2b: 46, C3bb: 46, B2: 47, B2n: -47, A2ss: 47, C3b: 47,
C3: 48, C3n: -48, B2s: 48, D3bb: 48, C3s: 49, B2ss: 49, D3b: 49, D3: 50, D3n: -50, C3ss: 50, E3bb: 50,
D3s: 51, E3b: 51, F3bb: 51, E3: 52, E3n: -52, D3ss: 52, F3b: 52, F3: 53, F3n: -53, E3s: 53, G3bb: 53,
A2: 45, A2n: -45, G2ss: 45, B2bb: 45, A2s: 46, B2b: 46, C3bb: 46, B2: 47, B2n: -47, A2ss: 47, C3b: 47,
C3: 48, C3n: -48, B2s: 48, D3bb: 48, C3s: 49, B2ss: 49, D3b: 49, D3: 50, D3n: -50, C3ss: 50, E3bb: 50,
D3s: 51, E3b: 51, F3bb: 51, E3: 52, E3n: -52, D3ss: 52, F3b: 52, F3: 53, F3n: -53, E3s: 53, G3bb: 53,
F3s: 54, E3ss: 54, G3b: 54, G3: 55, G3n: -55, F3ss: 55, A3bb: 55, G3s: 56, A3b: 56,
A3: 57, A3n: -57, G3ss: 57, B3bb: 57, A3s: 58, B3b: 58, C4bb: 58, B3: 59, B3n: -59, A3ss: 59, C4b: 59,
C4: 60, C4n: -60, B3s: 60, D4bb: 60, C4s: 61, B3ss: 61, D4b: 61, D4: 62, D4n: -62, C4ss: 62, E4bb: 62,
D4s: 63, E4b: 63, F4bb: 63, E4: 64, E4n: -64, D4ss: 64, F4b: 64, F4: 65, F4n: -65, E4s: 65, G4bb: 65,
A3: 57, A3n: -57, G3ss: 57, B3bb: 57, A3s: 58, B3b: 58, C4bb: 58, B3: 59, B3n: -59, A3ss: 59, C4b: 59,
C4: 60, C4n: -60, B3s: 60, D4bb: 60, C4s: 61, B3ss: 61, D4b: 61, D4: 62, D4n: -62, C4ss: 62, E4bb: 62,
D4s: 63, E4b: 63, F4bb: 63, E4: 64, E4n: -64, D4ss: 64, F4b: 64, F4: 65, F4n: -65, E4s: 65, G4bb: 65,
F4s: 66, E4ss: 66, G4b: 66, G4: 67, G4n: -67, F4ss: 67, A4bb: 67, G4s: 68, A4b: 68,
A4: 69, A4n: -69, G4ss: 69, B4bb: 69, A4s: 70, B4b: 70, C5bb: 70, B4: 71, B4n: -71, A4ss: 71, C5b: 71,
C5: 72, C5n: -72, B4s: 72, D5bb: 72, C5s: 73, B4ss: 73, D5b: 73, D5: 74, D5n: -74, C5ss: 74, E5bb: 74,
D5s: 75, E5b: 75, F5bb: 75, E5: 76, E5n: -76, D5ss: 76, F5b: 76, F5: 77, F5n: -77, E5s: 77, G5bb: 77,
A4: 69, A4n: -69, G4ss: 69, B4bb: 69, A4s: 70, B4b: 70, C5bb: 70, B4: 71, B4n: -71, A4ss: 71, C5b: 71,
C5: 72, C5n: -72, B4s: 72, D5bb: 72, C5s: 73, B4ss: 73, D5b: 73, D5: 74, D5n: -74, C5ss: 74, E5bb: 74,
D5s: 75, E5b: 75, F5bb: 75, E5: 76, E5n: -76, D5ss: 76, F5b: 76, F5: 77, F5n: -77, E5s: 77, G5bb: 77,
F5s: 78, E5ss: 78, G5b: 78, G5: 79, G5n: -79, F5ss: 79, A5bb: 79, G5s: 80, A5b: 80,
A5: 81, A5n: -81, G5ss: 81, B5bb: 81, A5s: 82, B5b: 82, C6bb: 82, B5: 83, B5n: -83, A5ss: 83, C6b: 83,
C6: 84, C6n: -84, B5s: 84, D6bb: 84, C6s: 85, B5ss: 85, D6b: 85, D6: 86, D6n: -86, C6ss: 86, E6bb: 86,
D6s: 87, E6b: 87, F6bb: 87, E6: 88, E6n: -88, D6ss: 88, F6b: 88, F6: 89, F6n: -89, E6s: 89, G6bb: 89,
A5: 81, A5n: -81, G5ss: 81, B5bb: 81, A5s: 82, B5b: 82, C6bb: 82, B5: 83, B5n: -83, A5ss: 83, C6b: 83,
C6: 84, C6n: -84, B5s: 84, D6bb: 84, C6s: 85, B5ss: 85, D6b: 85, D6: 86, D6n: -86, C6ss: 86, E6bb: 86,
D6s: 87, E6b: 87, F6bb: 87, E6: 88, E6n: -88, D6ss: 88, F6b: 88, F6: 89, F6n: -89, E6s: 89, G6bb: 89,
F6s: 90, E6ss: 90, G6b: 90, G6: 91, G6n: -91, F6ss: 91, A6bb: 91, G6s: 92, A6b: 92,
A6: 93, A6n: -93, G6ss: 93, B6bb: 93, A6s: 94, B6b: 94, C7bb: 94, B6: 95, B6n: -95, A6ss: 95, C7b: 95,
C7: 96, C7n: -96, B6s: 96, D7bb: 96, C7s: 97, B6ss: 97, D7b: 97, D7: 98, D7n: -98, C7ss: 98, E7bb: 98,
A6: 93, A6n: -93, G6ss: 93, B6bb: 93, A6s: 94, B6b: 94, C7bb: 94, B6: 95, B6n: -95, A6ss: 95, C7b: 95,
C7: 96, C7n: -96, B6s: 96, D7bb: 96, C7s: 97, B6ss: 97, D7b: 97, D7: 98, D7n: -98, C7ss: 98, E7bb: 98,
D7s: 99, E7b: 99, F7bb: 99, E7: 100, E7n: -100, D7ss: 100, F7b: 100, F7: 101, F7n: -101, E7s: 101, G7bb: 101,
F7s: 102, E7ss: 102, G7b: 102, G7: 103, G7n: -103, F7ss: 103, A7bb: 103, G7s: 104, A7b: 104,
A7: 105, A7n: -105, G7ss: 105, B7bb: 105, A7s: 106, B7b: 106, C8bb: 106, B7: 107, B7n: -107, A7ss: 107, C8b: 107,
Expand Down Expand Up @@ -139,7 +139,7 @@ export const AnalysisType = {
* @constant {Object<string, number>}
*/
export const EncodingType = {
WAV: 1
WAV: 1, WEBM: 2
};

/**
Expand Down
2 changes: 2 additions & 0 deletions library/webaudioapi/modules/Encoder.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

import { EncodingType } from './Constants.mjs';
import { WavFileEncoder } from '../encoders/WavFileEncoder.mjs';
import { WebmOpusEncoder } from '../encoders/WebmOpusEncoder.mjs';

const EncoderClasses = {
[EncodingType.WAV]: WavFileEncoder,
[EncodingType.WEBM]: WebmOpusEncoder,
};

/**
Expand Down
26 changes: 26 additions & 0 deletions library/webaudioapi/webAudioAPI.src.js
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,32 @@ export class WebAudioAPI {
return { getRawData, getDuration, finalize, getEncodedData, notifyWhenComplete };
}

/**
* Encodes a 2D array of floating point `samples` into a {@link https://developer.mozilla.org/en-US/docs/Web/API/Blob Blob}
* containing raw audio data according to the specified `sampleRate` and {@link module:Constants.EncodingType EncodingType}
* specified in the `encodingType` parameter.
*
* @param {number} encodingType - Numeric value corresponding to the desired {@link module:Constants.EncodingType EncodingType}
* @param {number} sampleRate - Sample rate at which the audio data was recorded
* @param {Array<Array<number>>} samples - 2D array of floating point audio samples to encode
* @returns {Blob} Data {@link https://developer.mozilla.org/en-US/docs/Web/API/Blob Blob} containing the newly encoded audio data
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Blob Blob}
* @see {@link module:Constants.EncodingType EncodingType}
*/
async encodeAudioAs(encodingType, sampleRate, samples) {
if (!Object.values(EncodingType).includes(Number(encodingType)))
throw new WebAudioApiErrors.WebAudioTargetError(`An encoder for the target type identifier (${encodingType}) does not exist`);
if (!samples || !samples.length || !Array.isArray(samples) || !(Array.isArray(samples[0])) || !samples[0].length)
throw new WebAudioApiErrors.WebAudioValueError('Cannot encode these audio samples because they are not a 2D array of floats');
const audioBuffer = this.#audioContext.createBuffer(samples.length, samples[0].length, sampleRate);
for (let ch = 0; ch < samples.length; ++ch) {
const channel_data = audioBuffer.getChannelData(ch);
for (let i = 0; i < samples[ch].length; ++i)
channel_data[i] = Math.min(Math.max(samples[ch][i], -1), 1);
}
return await getEncoderFor(Number(encodingType)).encode(audioBuffer);
}

/**
* Starts the {@link WebAudioAPI} library and allows audio playback to resume.
*/
Expand Down
3 changes: 2 additions & 1 deletion rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export default {
eslint({
exclude: [
'package.json',
'library/webaudioapi/modules/Constants.mjs'
'library/webaudioapi/modules/Constants.mjs',
'library/webaudioapi/encoders/webm-muxer.min.mjs',
],
}),
json()
Expand Down

0 comments on commit d595a33

Please sign in to comment.