Skip to content

Commit

Permalink
Using new WAV encoder which supports any source channels numbers and …
Browse files Browse the repository at this point in the history
…sample rate
  • Loading branch information
evanlouie committed Oct 11, 2018
1 parent 65b286e commit 8ed5731
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 193 deletions.
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
}
},
"dependencies": {
"@material-ui/core": "^3.1.2",
"@material-ui/core": "^3.2.0",
"@material-ui/icons": "^3.0.1",
"electron-compile": "^6.4.3",
"electron-devtools-installer": "^2.1.0",
Expand All @@ -68,19 +68,19 @@
"devDependencies": {
"@types/electron-devtools-installer": "^2.2.0",
"@types/fs-extra": "^5.0.4",
"@types/node": "^10.11.3",
"@types/react": "^16.4.14",
"@types/react-dom": "^16.0.8",
"@types/node": "^10.11.7",
"@types/react": "^16.4.16",
"@types/react-dom": "^16.0.9",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"electron-forge": "^5.2.2",
"electron-prebuilt-compile": "3.0.0",
"electron-prebuilt-compile": "3.0.2",
"prettier": "^1.14.3",
"tslint": "^5.1.0",
"tslint-config-prettier": "^1.15.0",
"tslint-react": "^3.6.0",
"typescript": "~3.1.1"
"typescript": "~3.1.2"
},
"prettier": {
"printWidth": 100,
Expand Down
2 changes: 1 addition & 1 deletion src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class App extends React.Component<any, IAppState> {
))}
{currentPage === "classifications" && <ClassificationTable />}
{!currentPage && (
<Typography variant="body1">Select audio file before to begin labelling</Typography>
<Typography variant="body2">Select audio file before to begin labelling</Typography>
)}
</main>
<NotificationContext.Consumer>
Expand Down
37 changes: 24 additions & 13 deletions src/components/AudioPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { Label } from "../entities/Label"
import { sliceAudioBuffer } from "../lib/audio"
import { stringToRGBA } from "../lib/colour"
import { getDBConnection } from "../lib/database"
import { WavEncoder } from "../lib/WavEncoder"
import { WavAudioEncoder } from "../lib/WavAudioEncoder"
import { LabelTable } from "./LabelTable"

export interface IAudioPlayerProps {
Expand Down Expand Up @@ -198,14 +198,16 @@ export class AudioPlayer extends React.PureComponent<IAudioPlayerProps, IAudioPl
]).then(([audioBuffer, labelsWithSample]) => {
labelsWithSample.forEach((labelWithSample) => {
const { sampleData } = labelWithSample
sliceAudioBuffer(audioBuffer, label.startTime, label.endTime).then(
(slicedSegment) => {
sampleData.blob = Buffer.from(WavEncoder.encode(slicedSegment))
sliceAudioBuffer(audioBuffer, label.startTime, label.endTime)
.then((slicedSegment) => {
return new Response(WavAudioEncoder.encode(slicedSegment)).arrayBuffer()
})
.then((arrayBuffer) => {
sampleData.blob = Buffer.from(arrayBuffer)
sampleData.save().then((updated) => {
console.info(`Updated DataBlob ${updated.id}`)
})
},
)
})
})
})
})
Expand Down Expand Up @@ -446,11 +448,12 @@ export class AudioPlayer extends React.PureComponent<IAudioPlayerProps, IAudioPl
const audioBuffer = await audioBuffer_
const slicedSegment = await sliceAudioBuffer(audioBuffer, label.startTime, endTime)
// DANGEROUS!! Using Node `Buffer` in front-end code so we can save the segment to DB. Will appear as a Uint8Array on client side when queried
const arrayBuffer = await new Response(WavAudioEncoder.encode(slicedSegment)).arrayBuffer()
const [audioFile, classification, sampleData] = await Promise.all([
audioFile_,
classification_,
DataBlob.create({
blob: Buffer.from(WavEncoder.encode(slicedSegment)),
blob: Buffer.from(arrayBuffer),
}).save(),
])
const wavesurferRegion = {
Expand Down Expand Up @@ -585,11 +588,12 @@ export class AudioPlayer extends React.PureComponent<IAudioPlayerProps, IAudioPl

const audioBuffer = await audioBuffer_
const slicedBuffer = await sliceAudioBuffer(audioBuffer, region.start, region.end)
const arrayBuffer = await new Response(WavAudioEncoder.encode(slicedBuffer)).arrayBuffer()
const [audioFile, classification, sampleData] = await Promise.all([
audioFile_,
this.getClassification(label),
DataBlob.create({
blob: Buffer.from(WavEncoder.encode(slicedBuffer)),
blob: Buffer.from(arrayBuffer),
}).save(),
])

Expand Down Expand Up @@ -624,6 +628,9 @@ export class AudioPlayer extends React.PureComponent<IAudioPlayerProps, IAudioPl
}

private handlePlayLabel = async ({ id: targetLabelId }: Label) => {
// Debug: Play the actual stored audio instead
// Label.playAudio(targetLabelId)

const wavesurfer = await this.wavesurfer()
this.state.wavesurferRegionIdToLabelIdMap
.filter((labelId) => labelId === targetLabelId)
Expand Down Expand Up @@ -662,11 +669,15 @@ export class AudioPlayer extends React.PureComponent<IAudioPlayerProps, IAudioPl
labelsWithSample.map((labelWithSample) => {
const { sampleData, startTime, endTime } = labelWithSample
return sliceAudioBuffer(audioBuffer, startTime, endTime).then((slicedSegment) => {
sampleData.blob = Buffer.from(WavEncoder.encode(slicedSegment))
return sampleData.save().then((updated) => {
console.info(`Updated DataBlob ${updated.id}`)
return updated
})
return new Response(WavAudioEncoder.encode(slicedSegment))
.arrayBuffer()
.then((arrBuffer) => {
sampleData.blob = Buffer.from(arrBuffer)
return sampleData.save().then((updated) => {
console.info(`Updated DataBlob ${updated.id}`)
return updated
})
})
})
}),
)
Expand Down
13 changes: 2 additions & 11 deletions src/components/ClassificationTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class LabelTableModal extends React.PureComponent<{
<IconButton color="inherit" onClick={this.handleClose} aria-label="Close">
<Close />
</IconButton>
<Typography variant="title" color="inherit">
<Typography variant="h6" color="inherit">
{name}
</Typography>
</Toolbar>
Expand All @@ -197,16 +197,7 @@ class LabelTableModal extends React.PureComponent<{
labels={labels}
currentlyPlayingLabelIds={currentlyPlayingLabelIds}
playLabel={async (label: Label) => {
Label.getRepository()
.find({ relations: ["sampleData"], where: { id: label.id } })
.then((labelsWithSample) => {
labelsWithSample.forEach(async (labelWithSample) => {
const blob = await new Response(labelWithSample.sampleData.blob).blob()
const url = URL.createObjectURL(blob)
const audio = new Audio(url)
audio.play()
})
})
Label.playAudio(label.id)
}}
deleteLabel={async (targetLabel: Label) => {
Label.getRepository()
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const Header: React.StatelessComponent = () => (
<IconButton color="inherit" aria-label="Menu">
<Menu />
</IconButton>
<Typography variant="title" color="inherit">
<Typography variant="h6" color="inherit">
ReverbML
</Typography>
</Toolbar>
Expand Down
13 changes: 13 additions & 0 deletions src/entities/Label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ import { DataBlob } from "./DataBlob"

@Entity()
export class Label extends BaseEntity {
public static async playAudio(labelId: number) {
Label.getRepository()
.find({ relations: ["sampleData"], where: { id: labelId } })
.then((labelsWithSample) => {
labelsWithSample.forEach(async (labelWithSample) => {
const blob = await new Response(labelWithSample.sampleData.blob).blob()
const url = URL.createObjectURL(blob)
const audio = new Audio(url)
audio.play()
})
})
}

@PrimaryGeneratedColumn()
public id!: number

Expand Down
1 change: 1 addition & 0 deletions src/lib/WavAudioEncoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export class WavAudioEncoder {
public static encode(buffer: AudioBuffer): Blob {
const { sampleRate, numberOfChannels } = buffer
const encoder = new WavAudioEncoder(sampleRate, numberOfChannels)
console.log(sampleRate)
const float32buffers = [...Array(numberOfChannels)].map((_, i) => buffer.getChannelData(i))
encoder.encode(float32buffers)
return encoder.finish()
Expand Down
Loading

0 comments on commit 8ed5731

Please sign in to comment.