Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ts resolve #538

Merged
merged 5 commits into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ overrides:
no-use-before-define: off
import/no-unresolved: off
import/export: off
no-useless-constructor: off
2 changes: 1 addition & 1 deletion config/webpackResolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ module.exports = {
alias: {
bemuse: path('src'),
},
extensions: ['.webpack.js', '.web.js', '.js', '.jsx'],
extensions: ['.webpack.js', '.web.js', '.js', '.jsx', '.ts', '.tsx'],
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
},
"homepage": "https://github.com/spacetme/bemuse",
"devDependencies": {
"@types/chai": "^4.2.0",
"@types/eslint": "^4.16.4",
"@types/minimatch": "^3.0.3",
"autoprefixer": "^9.1.5",
Expand Down
92 changes: 0 additions & 92 deletions src/sampling-master/ogg.js

This file was deleted.

File renamed without changes.
105 changes: 105 additions & 0 deletions src/sampling-master/ogg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import throat from 'throat'

type OGGDecodeEvent = {
data?: Float32Array[]
sampleRate: number
error?: any
eof?: boolean
}

type OGGDecoder = {
decode(arrayBuffer: ArrayBuffer, callback: (e: OGGDecodeEvent) => void): void
}

let decoderPromise: Promise<OGGDecoder>

const limit = throat(1)

function getDecoder() {
if (!decoderPromise) {
// @ts-ignore
decoderPromise = import(/* webpackChunkName: 'stbvorbis' */ 'raw-loader!./vendor/stbvorbis/stbvorbis-e6da5fe.js')
.then(ns => ns.default)
.then(src => {
// eslint-disable-next-line no-eval
return (0, eval)(src + ';stbvorbis')
})
}
return decoderPromise
}

/**
* Decodes an OGG file using stbvorbis.js.
*/
export async function decodeOGG(
audioContext: AudioContext,
arrayBuffer: ArrayBuffer
) {
const stbvorbis = await getDecoder()
return limit(() => doDecodeOGG(stbvorbis, audioContext, arrayBuffer))
}

function doDecodeOGG(
stbvorbis: OGGDecoder,
audioContext: AudioContext,
arrayBuffer: ArrayBuffer
) {
return new Promise<AudioBuffer>((resolve, reject) => {
const buffers: Float32Array[][] = []
let totalLength = 0
let sampleRate: number
stbvorbis.decode(arrayBuffer, function(e) {
if (e.data) {
sampleRate = e.sampleRate
buffers.push(e.data)
totalLength += e.data[0].length
}
if (e.error) {
const error =
e.error instanceof Error ? e.error : `stbvorbis.js Error: ${e.error}`
reject(error)
}
if (e.eof) {
resolve(createBuffer(audioContext, buffers, totalLength, sampleRate))
}
})
})
}

async function createBuffer(
audioContext: AudioContext,
decodedChunks: Float32Array[][],
length: number,
sampleRate: number
) {
if (!length) throw new Error(`stbvorbis.js Error: No length`)
if (!sampleRate) throw new Error(`stbvorbis.js Error: No sample rate`)
const numberOfChannels = decodedChunks[0].length
const audioBuffer = audioContext.createBuffer(
numberOfChannels,
length,
sampleRate
)
const channels: ChannelDataWriter[] = Array(audioBuffer.numberOfChannels)
.fill(null)
.map((_, ch) => new ChannelDataWriter(audioBuffer.getChannelData(ch)))
for (const chunk of decodedChunks) {
chunk.forEach((audioSamples, channelIndex) => {
channels[channelIndex].write(audioSamples)
})
}
return audioBuffer
}

class ChannelDataWriter {
private offset = 0
constructor(private data: Float32Array) {}
write(audioSamples: Float32Array) {
// iOS Safari does not support `buf.copyToChannel(a, ch, track[ch])`, so we had to copy audio data sample-by-sample.
const { offset, data } = this
for (var i = 0; i < audioSamples.length; i++) {
data[i + offset] = audioSamples[i]
}
this.offset += audioSamples.length
}
}
2 changes: 1 addition & 1 deletion src/test/loadSpecs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export function loadSpecs() {
const context = require.context('..', true, /\.spec\.js$/)
const context = require.context('..', true, /\.spec\.[jt]sx?$/)
for (const key of context.keys()) {
describe(key, () => {
context(key)
Expand Down
1 change: 1 addition & 0 deletions types/chai.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare var expect: (typeof import('chai'))['expect']
6 changes: 6 additions & 0 deletions types/throat.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare module 'throat' {
var throat: {
(concurrency: number): <R>(fn: () => Promise<R>) => Promise<R>
}
export = throat
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,11 @@
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a"
integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==

"@types/chai@^4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.0.tgz#2478260021408dec32c123a7cad3414beb811a07"
integrity sha512-zw8UvoBEImn392tLjxoavuonblX/4Yb9ha4KBU10FirCfwgzhKO0dvyJSF9ByxV1xK1r2AgnAi/tvQaLgxQqxA==

"@types/cheerio@^0.22.8":
version "0.22.9"
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.9.tgz#b5990152604c2ada749b7f88cab3476f21f39d7b"
Expand Down