Skip to content
Open
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
34 changes: 17 additions & 17 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
Expand Up @@ -17,7 +17,7 @@
"@mantine/core": "^7.1.5",
"@mantine/form": "^7.1.7",
"@mantine/hooks": "^7.1.5",
"@p5-wrapper/react": "^4.2.0",
"@p5-wrapper/react": "^4.4.0",
"@reduxjs/toolkit": "^1.9.7",
"@tabler/icons-react": "^2.39.0",
"clsx": "^2.0.0",
Expand Down
20 changes: 20 additions & 0 deletions src/components/CreateOutput/CreateOutput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { ReactNode, useEffect } from "react"
import treingvbluesberber from "../../assets/music/treingvbluesberber.mp3"
import P5WaveFormSketchWrapper from "../../pages/patternmaker-page/components/P5WaveFormSketchWrapper"
import * as Tone from "tone"

interface CreateOutputProps {
children: ReactNode
}
const channel = new Tone.Channel(-0.25, -1)
const output = new Tone.Volume(-12).toDestination()
const lpFilter = new Tone.Filter(8000, "lowpass", -48).connect(output)
const hpFilter = new Tone.Filter(0, "highpass").connect(lpFilter)

function CreateOutput({ children }: CreateOutputProps) {
// console.log("hoi")

return <div>{children}</div>
}

export default CreateOutput
19 changes: 14 additions & 5 deletions src/components/WaveSurferPlayer/BlankWaveSurfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const BlankWaveSurfer: React.FC<WaveSurferOptions> = (props) => {
const [loop, setLoop] = useState<boolean>(false)
const [activeRegion, setActiveRegion] = useState<Region | null>(null)
const [cuePoint, setCuePoint] = useState<Region | null>(null)
const [pitchValue, setPitchValue] = useState(0.5)

useEffect(() => {
if (!wavesurfer) return
Expand All @@ -56,13 +57,13 @@ const BlankWaveSurfer: React.FC<WaveSurferOptions> = (props) => {
// WAVESURFER INIT
useEffect(() => {
if (!wavesurfer || !wsRegions) return
// setCurrentTime(0)

const subscriptions = [
wavesurfer.on("play", () => setIsPlaying(true)),
wavesurfer.on("pause", () => setIsPlaying(false)),
wavesurfer.on("timeupdate", (currentTime) => setCurrentTime(currentTime)),
wavesurfer.on("zoom", (e) => {
wavesurfer.on("timeupdate", (currentTime: number) =>
setCurrentTime(currentTime),
),
wavesurfer.on("zoom", (e: number) => {
setZoom(e), setCurrentTime(currentTime)
}),
]
Expand Down Expand Up @@ -142,12 +143,13 @@ const BlankWaveSurfer: React.FC<WaveSurferOptions> = (props) => {

// FOLLOW
useEffect(() => {
wavesurfer?.setOptions({ autoScroll: follow })
wavesurfer?.setOptions({ autoScroll: follow, autoCenter: follow })
}, [follow, wavesurfer])

// PLAY
const onPlayClick = useCallback(() => {
if (!wavesurfer) return
console.log(wavesurfer.isPlaying())
wavesurfer.isPlaying() ? wavesurfer.pause() : wavesurfer?.playPause()
}, [wavesurfer])

Expand Down Expand Up @@ -203,6 +205,8 @@ const BlankWaveSurfer: React.FC<WaveSurferOptions> = (props) => {
changePitch={(e: number) => {
if (e > 0.07) wavesurfer!.setPlaybackRate(e, false)
}}
setPitchValue={setPitchValue}
pitchValue={pitchValue}
/>
</Flex>
<Group
Expand Down Expand Up @@ -295,6 +299,11 @@ const BlankWaveSurfer: React.FC<WaveSurferOptions> = (props) => {
<IconZoomIn onClick={() => wavesurfer?.zoom(zoom + 5)} />
</Group>
</Group>
{/* <Group>
<Box w="100%" h="30vh" bg="grape">
<Text>Hoi ik zit in de doos</Text>
</Box>
</Group> */}
</Box>
)
}
Expand Down
14 changes: 9 additions & 5 deletions src/components/WaveSurferPlayer/PitchSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { useState } from "react"
import { Group, Stack, rem } from "@mantine/core"
import { useMove } from "@mantine/hooks"

interface PitchSliderProps {
changePitch: (y: number) => void
setPitchValue: (y: number) => void
pitchValue: number
}

const PitchSlider: React.FC<PitchSliderProps> = ({ changePitch }) => {
const [value, setValue] = useState(0.5)
const PitchSlider: React.FC<PitchSliderProps> = ({
changePitch,
setPitchValue,
pitchValue,
}) => {
const { ref } = useMove(({ y }) => setter(y))

const setter = (y: number) => {
setValue(y)
setPitchValue(y)
// changePitch(y * 0.25 + 0.875);
// changePitch(y * 0.5 + 0.75);
// changePitch(y * 1 + 0.5);
Expand All @@ -36,7 +40,7 @@ const PitchSlider: React.FC<PitchSliderProps> = ({ changePitch }) => {
<div
style={{
position: "absolute",
top: `calc(${value * 99}%`,
top: `calc(${pitchValue * 99}%`,
left: 0,
width: rem(16),
height: rem(1),
Expand Down
88 changes: 88 additions & 0 deletions src/components/audiocontext/AudioAnalyser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useState, useRef } from "react"

interface AudioAnalyserProps {
audiofile: string
}

const AudioAnalyser: React.FC<AudioAnalyserProps> = ({ audiofile }) => {
const [isPlaying, setIsPlaying] = useState(false)
const audioRef = useRef<HTMLAudioElement>(null)
const canvasRef = useRef<HTMLCanvasElement>(null)
const animationRef = useRef<number | null>(null)

const startAudio = async () => {
try {
const audioContext = new window.AudioContext()
const audioElement = audioRef.current
const canvasElement = canvasRef.current

if (!audioElement || !canvasElement) return

const sourceNode = audioContext.createMediaElementSource(audioElement)
const analyserNode = audioContext.createAnalyser()
analyserNode.fftSize = 2048
const javascriptNode = audioContext.createScriptProcessor(2048, 1, 1)

sourceNode.connect(analyserNode)
analyserNode.connect(audioContext.destination)
analyserNode.connect(javascriptNode)
javascriptNode.connect(audioContext.destination)

setIsPlaying(true)

const draw = () => {
const canvasContext = canvasElement.getContext("2d")
const bufferLength = analyserNode.frequencyBinCount
const dataArray = new Uint8Array(bufferLength)
analyserNode.getByteTimeDomainData(dataArray)
if (!canvasContext) return
canvasContext.clearRect(0, 0, canvasElement.width, canvasElement.height)
canvasContext.fillStyle = "rgb(255, 255, 255)"
canvasContext.fillRect(0, 0, canvasElement.width, canvasElement.height)
canvasContext.lineWidth = 2
canvasContext.strokeStyle = "rgb(0, 0, 0)"
canvasContext.beginPath()

const sliceWidth = (canvasElement.width * 1.0) / bufferLength
let x = 0

for (let i = 0; i < bufferLength; i++) {
const v = dataArray[i] / 128.0
const y = (v * canvasElement.height) / 2

if (i === 0) {
canvasContext.moveTo(x, y)
} else {
canvasContext.lineTo(x, y)
}

x += sliceWidth
}

canvasContext.lineTo(canvasElement.width, canvasElement.height / 2)
canvasContext.stroke()

animationRef.current = requestAnimationFrame(draw)
}

audioElement.play()
draw()
} catch (error) {
console.error("Error starting audio:", error)
}
}

startAudio()
return (
<div>
<canvas ref={canvasRef} width="512" height="256"></canvas>

<div id="controls">
<output id="msg">{isPlaying ? "Audio playing..." : ""}</output>
</div>
<audio controls ref={audioRef} src={audiofile}></audio>
</div>
)
}

export default AudioAnalyser
Loading