@@ -18,18 +18,39 @@ interface PlayerProps {
1818 musicList : Music [ ] ;
1919}
2020
21+ // イコライザのプリセットを定義
22+ const equalizerPresets : { [ key : string ] : number [ ] } = {
23+ Flat : [ 0 , 0 , 0 , 0 , 0 ] ,
24+ Rock : [ 4 , 2 , 0 , 2 , 4 ] ,
25+ Pop : [ 2 , 4 , 2 , - 2 , - 4 ] ,
26+ BassBoost : [ 6 , 4 , 0 , - 2 , - 4 ] ,
27+ TrebleBoost : [ - 4 , - 2 , 0 , 4 , 6 ] ,
28+ Jazz : [ 2 , 0 , 4 , 2 , 0 ] ,
29+ Classical : [ 0 , 2 , 4 , 0 , - 2 ] ,
30+ Acoustic : [ 0 , 4 , 2 , - 2 , - 4 ] ,
31+ Dance : [ 4 , 2 , 0 , 4 , 6 ] ,
32+ HipHop : [ 2 , 4 , 0 , - 2 , 0 ] ,
33+ RnB : [ 0 , 2 , 4 , 2 , 0 ] ,
34+ Country : [ 0 , 0 , 2 , 4 , 2 ] ,
35+ Blues : [ 0 , 2 , 4 , 0 , - 2 ] ,
36+ Reggae : [ 2 , 0 , - 2 , 4 , 6 ] ,
37+ Electronic : [ 4 , 2 , 0 , - 2 , 0 ] ,
38+ Indie : [ 0 , 4 , 2 , - 2 , - 4 ] ,
39+ Metal : [ 6 , 4 , 0 , - 2 , - 4 ] ,
40+ Custom : [ 0 , 0 , 0 , 0 , 0 ] , // Custom preset for manual adjustments
41+ } ;
42+
2143export function Player ( { music, musicList } : PlayerProps ) {
2244 const t = useTranslations ( "pages.music.player" ) ;
2345 const [ playState , setPlayState ] = useState < "stop" | "play" > ( "stop" ) ;
2446 const [ duration , setDuration ] = useState ( 0 ) ;
2547 const [ timePosition , setTimePosition ] = useState ( 0 ) ;
2648 const [ playbackRate , setPlaybackRate ] = useState ( 1 ) ;
27- const [ source , setSource ] = useState < MediaElementAudioSourceNode | null > (
28- null
29- ) ;
49+ const [ source , setSource ] = useState < MediaElementAudioSourceNode | null > ( null ) ;
3050 const [ analyserNode , setAnalyserNode ] = useState < AnalyserNode | null > ( null ) ;
3151 const [ isCircular , setIsCircular ] = useState ( false ) ;
32- const [ eqGains , setEqGains ] = useState < number [ ] > ( [ 0 , 0 , 0 , 0 , 0 ] ) ;
52+ const [ eqGains , setEqGains ] = useState < number [ ] > ( equalizerPresets . Flat ) ; // 初期値はFlat
53+ const [ selectedPreset , setSelectedPreset ] = useState < string > ( "Flat" ) ;
3354
3455 const audioRef = useRef < HTMLAudioElement > ( null ) ;
3556 const audioCtxRef = useRef < AudioContext | null > ( null ) ;
@@ -125,6 +146,7 @@ export function Player({ music, musicList }: PlayerProps) {
125146 filter . disconnect ( ) ;
126147 } ) ;
127148 } ;
149+ //lint-disable-next-line
128150 } , [ ] ) ;
129151
130152 useEffect ( ( ) => {
@@ -214,7 +236,7 @@ export function Player({ music, musicList }: PlayerProps) {
214236 0 ,
215237 0
216238 ) ;
217- gradient . addColorStop ( 0 , `hsla(${ hue } , 100%, 50%, 0.8 )` ) ;
239+ gradient . addColorStop ( 0 , `hsla(${ hue } , 100%, 50%, 0.4 )` ) ;
218240 gradient . addColorStop ( 1 , `hsla(${ hue } , 100%, 50%, 0.2)` ) ;
219241
220242 canvasCtx . fillStyle = gradient ;
@@ -231,7 +253,6 @@ export function Player({ music, musicList }: PlayerProps) {
231253 animationFrameRef . current = requestAnimationFrame ( renderFrame ) ;
232254 } ;
233255
234- // 初回描画を即座に開始
235256 renderFrame ( ) ;
236257
237258 return ( ) => {
@@ -353,6 +374,13 @@ export function Player({ music, musicList }: PlayerProps) {
353374 const newGains = [ ...eqGains ] ;
354375 newGains [ index ] = parseFloat ( e . target . value ) ;
355376 setEqGains ( newGains ) ;
377+ setSelectedPreset ( "Custom" ) ; // 手動で変更したらプリセットをCustomに
378+ } ;
379+
380+ const handlePresetChange = ( e : React . ChangeEvent < HTMLSelectElement > ) => {
381+ const presetName = e . target . value ;
382+ setSelectedPreset ( presetName ) ;
383+ setEqGains ( equalizerPresets [ presetName ] ) ;
356384 } ;
357385
358386 return (
@@ -474,7 +502,24 @@ export function Player({ music, musicList }: PlayerProps) {
474502 < details >
475503 < summary > { t ( "equalizer" ) } </ summary >
476504 < div className = { styles [ "eq-controls" ] } >
505+ < div className = { styles [ "eq-preset" ] } >
506+ < label htmlFor = "eqPreset" > { t ( "preset" ) } </ label >
507+ < select
508+ id = "eqPreset"
509+ value = { selectedPreset }
510+ onChange = { handlePresetChange }
511+ className = { styles [ "eq-preset-select" ] }
512+ >
513+ { Object . keys ( equalizerPresets ) . map ( ( preset ) => (
514+ < option key = { preset } value = { preset } >
515+ { preset }
516+ </ option >
517+ ) ) }
518+ < option value = "Custom" > Custom</ option >
519+ </ select >
520+ </ div >
477521 < div className = { styles [ "eq-slider" ] } >
522+ < label > 60 Hz</ label >
478523 < input
479524 type = "range"
480525 min = "-12"
@@ -485,6 +530,7 @@ export function Player({ music, musicList }: PlayerProps) {
485530 />
486531 </ div >
487532 < div className = { styles [ "eq-slider" ] } >
533+ < label > 250 Hz</ label >
488534 < input
489535 type = "range"
490536 min = "-12"
@@ -495,6 +541,7 @@ export function Player({ music, musicList }: PlayerProps) {
495541 />
496542 </ div >
497543 < div className = { styles [ "eq-slider" ] } >
544+ < label > 1 kHz</ label >
498545 < input
499546 type = "range"
500547 min = "-12"
@@ -505,6 +552,7 @@ export function Player({ music, musicList }: PlayerProps) {
505552 />
506553 </ div >
507554 < div className = { styles [ "eq-slider" ] } >
555+ < label > 4 kHz</ label >
508556 < input
509557 type = "range"
510558 min = "-12"
@@ -515,6 +563,7 @@ export function Player({ music, musicList }: PlayerProps) {
515563 />
516564 </ div >
517565 < div className = { styles [ "eq-slider" ] } >
566+ < label > 16 kHz</ label >
518567 < input
519568 type = "range"
520569 min = "-12"
@@ -567,4 +616,4 @@ export function Player({ music, musicList }: PlayerProps) {
567616 </ section >
568617 </ div >
569618 ) ;
570- }
619+ }
0 commit comments