-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.js
149 lines (125 loc) · 3.76 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/**
* @module audio-dtype
*/
'use strict'
var AudioBuffer = require('audio-buffer')
var isAudioBuffer = require('is-audio-buffer')
var isObj = require('is-plain-obj')
var getContext = require('audio-context')
var convert = require('pcm-convert')
var format = require('audio-format')
var str2ab = require('string-to-arraybuffer')
var pick = require('pick-by-alias')
module.exports = function createBuffer (source, options) {
var length, data, channels, sampleRate, format, c, l
//src, channels
if (typeof options === 'number') {
options = {channels: options}
}
else if (typeof options === 'string') {
options = {format: options}
}
//{}
else if (options === undefined) {
if (isObj(source)) {
options = source
source = undefined
}
else {
options = {}
}
}
options = pick(options, {
format: 'format type dtype dataType',
channels: 'channel channels numberOfChannels channelCount',
sampleRate: 'sampleRate rate',
length: 'length size',
duration: 'duration time'
})
//detect options
channels = options.channels
sampleRate = options.sampleRate
if (options.format) format = getFormat(options.format)
if (format) {
if (channels && !format.channels) format.channels = channels
else if (format.channels && !channels) channels = format.channels
if (!sampleRate && format.sampleRate) sampleRate = format.sampleRate
}
//empty buffer
if (source == null) {
if (options.duration != null) {
if (!sampleRate) sampleRate = 44100
length = sampleRate * options.duration
}
else length = options.length
}
//if audio buffer passed - create fast clone of it
else if (isAudioBuffer(source)) {
length = source.length
if (channels == null) channels = source.numberOfChannels
if (sampleRate == null) sampleRate = source.sampleRate
if (source._channelData) {
data = source._channelData.slice(0, channels)
}
else {
data = []
for (c = 0, l = channels; c < l; c++) {
data[c] = source.getChannelData(c)
}
}
}
//if create(number, channels? rate?) = create new array
//this is the default WAA-compatible case
else if (typeof source === 'number') {
length = source
}
//if array with channels - parse channeled data
else if (Array.isArray(source) && (Array.isArray(source[0]) || ArrayBuffer.isView(source[0]))) {
length = source[0].length;
data = []
if (!channels) channels = source.length
for (c = 0; c < channels; c++) {
data[c] = source[c] instanceof Float32Array ? source[c] : new Float32Array(source[c])
}
}
//if ndarray, ndsamples, or anything with data
else if (source.shape && source.data) {
if (source.shape) channels = source.shape[1]
if (!sampleRate && source.format) sampleRate = source.format.sampleRate
return createBuffer(source.data, {
channels: channels,
sampleRate: sampleRate
})
}
//TypedArray, Buffer, DataView etc, ArrayBuffer, Array etc.
//NOTE: node 4.x+ detects Buffer as ArrayBuffer view
else {
if (typeof source === 'string') {
source = str2ab(source)
}
if (!format) format = getFormat(source)
if (!channels) channels = format.channels || 1
source = convert(source, format, 'float32 planar')
length = Math.floor(source.length / channels);
data = []
for (c = 0; c < channels; c++) {
data[c] = source.subarray(c * length, (c + 1) * length);
}
}
//create buffer of proper length
var audioBuffer = new AudioBuffer((options.context === null || length === 0) ? null : options.context || getContext(), {
length: length == null ? 1 : length,
numberOfChannels: channels || 1,
sampleRate: sampleRate || 44100
})
//fill channels
if (data) {
for (c = 0, l = data.length; c < l; c++) {
audioBuffer.getChannelData(c).set(data[c]);
}
}
return audioBuffer
}
function getFormat (arg) {
return typeof arg === 'string' ? format.parse(arg) : format.detect(arg)
}