Skip to content

Commit

Permalink
Merge pull request #136 from staskobzar/fix-waveform-dup
Browse files Browse the repository at this point in the history
[#135] fix waveform and release
  • Loading branch information
staskobzar authored May 9, 2023
2 parents bde8904 + 6f1e83a commit ded14bb
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 51 deletions.
1 change: 1 addition & 0 deletions docs/assets/index.81e19f17.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion docs/assets/index.eafff7c1.js

This file was deleted.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Vue audio visual plugin demo</title>
<script type="module" crossorigin src="/vue-audio-visual/assets/index.eafff7c1.js"></script>
<script type="module" crossorigin src="/vue-audio-visual/assets/index.81e19f17.js"></script>
</head>

<body>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-audio-visual",
"version": "3.0.4",
"version": "3.0.5",
"type": "module",
"files": [
"dist"
Expand Down
51 changes: 5 additions & 46 deletions src/composables/useAVWaveform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { useCanvasContext } from '@/composables/useCanvasContext'
import { Waveform, type PropsWaveformType } from '@/composables/useProps'
import { createFetch, resolveUnref, useEventListener, useRafFn, type CreateFetchOptions } from '@vueuse/core'

const peaks: [number, number][] = []

export function useAVWaveform<T extends object>(
player: Ref<HTMLAudioElement | null>,
canvas: Ref<HTMLCanvasElement | null>,
Expand Down Expand Up @@ -61,18 +59,18 @@ export function draw(canvas: Ref<CanvasRenderingContext2D | null>, p: Waveform)
const waveform = (x: number, to: number, lw: number, color: string): number => {
ctx.lineWidth = lw
ctx.strokeStyle = color
to = to > peaks.length ? peaks.length : to
to = to > p.peaks.length ? p.peaks.length : to
ctx.beginPath()
for (; x < to; x++) {
ctx.moveTo(x, peaks[x][0])
ctx.lineTo(x, peaks[x][1])
ctx.moveTo(x, p.peaks[x][0])
ctx.lineTo(x, p.peaks[x][1])
}
ctx.stroke()
return x
}

x = waveform(x, p.playX, p.playedLineWidth, p.playedLineColor)
waveform(x, peaks.length, p.noplayedLineWidth, p.noplayedLineColor)
waveform(x, p.peaks.length, p.noplayedLineWidth, p.noplayedLineColor)

drawSlider(ctx, p)

Expand Down Expand Up @@ -122,7 +120,7 @@ function fetchData(canv: Ref<CanvasRenderingContext2D | null>, p: Waveform, fetc
const ctx = new AudioContext()
ctx.decodeAudioData(data.value).then(buff => {
p.duration = buff.duration
setPeaks(buff, p)
p.setPeaks(buff)
draw(canv, p)
}).catch(err => {
console.error('Failed to decode audio array buffer:', err)
Expand All @@ -144,42 +142,3 @@ function fetchData(canv: Ref<CanvasRenderingContext2D | null>, p: Waveform, fetc
}
})
}

function setPeaks(buffer: AudioBuffer, p: Waveform) {
peaks.slice(0)
let min = 0
let max = 0
let top = 0
let bottom = 0
const segSize = Math.ceil(buffer.length / p.canvWidth)
const width = p.canvWidth
const height = p.canvHeight

for (let c = 0; c < buffer.numberOfChannels; c++) {
const data = buffer.getChannelData(c)
for (let s = 0; s < width; s++) {
const start = ~~(s * segSize)
const end = ~~(start + segSize)
min = 0
max = 0
for (let i = start; i < end; i++) {
min = data[i] < min ? data[i] : min
max = data[i] > max ? data[i] : max
}
// merge multi channel data
if (peaks[s]) {
peaks[s][0] = peaks[s][0] < max ? max : peaks[s][0]
peaks[s][1] = peaks[s][1] > min ? min : peaks[s][1]
}
peaks[s] = [max, min]
}
}
// set peaks relativelly to canvas dimensions
for (let i = 0; i < peaks.length; i++) {
max = peaks[i][0]
min = peaks[i][1]
top = ((height / 2) - (max * height / 2))
bottom = ((height / 2) - (min * height / 2))
peaks[i] = [top, bottom === top ? top + 1 : bottom]
}
}
40 changes: 40 additions & 0 deletions src/composables/useProps/Waveform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ export class Waveform {
playtimeSliderColor: string
playtimeSliderWidth: number
playtimeClickable: boolean
peaks: [number, number][] = []
constructor(p: PropsWaveformType) {
const w = PropsWaveform
this.canvWidth = resolvePropNum(p.canvWidth, w.canvWidth.default)
Expand Down Expand Up @@ -227,4 +228,43 @@ export class Waveform {
const ms = ~~(this.currentTime % 1 * 1000)
return [time, String(ms).padStart(3, '0')].join('.')
}

setPeaks(buffer: AudioBuffer) {
this.peaks.slice(0)
let min = 0
let max = 0
let top = 0
let bottom = 0
const segSize = Math.ceil(buffer.length / this.canvWidth)
const width = this.canvWidth
const height = this.canvHeight

for (let c = 0; c < buffer.numberOfChannels; c++) {
const data = buffer.getChannelData(c)
for (let s = 0; s < width; s++) {
const start = ~~(s * segSize)
const end = ~~(start + segSize)
min = 0
max = 0
for (let i = start; i < end; i++) {
min = data[i] < min ? data[i] : min
max = data[i] > max ? data[i] : max
}
// merge multi channel data
if (this.peaks[s]) {
this.peaks[s][0] = this.peaks[s][0] < max ? max : this.peaks[s][0]
this.peaks[s][1] = this.peaks[s][1] > min ? min : this.peaks[s][1]
}
this.peaks[s] = [max, min]
}
}
// set peaks relativelly to canvas dimensions
for (let i = 0; i < this.peaks.length; i++) {
max = this.peaks[i][0]
min = this.peaks[i][1]
top = ((height / 2) - (max * height / 2))
bottom = ((height / 2) - (min * height / 2))
this.peaks[i] = [top, bottom === top ? top + 1 : bottom]
}
}
}

0 comments on commit ded14bb

Please sign in to comment.