diff --git a/_data/src_audio_files.json b/_data/src_audio_files.json
deleted file mode 100644
index b95ea39..0000000
--- a/_data/src_audio_files.json
+++ /dev/null
@@ -1,242 +0,0 @@
-[
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/stop01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/start01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/warp01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/wind_chimes01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/start02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/explode01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/scratch01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/filter_sweep01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/chroma_sound_effect01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/effects/warp02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/applause01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/undefined01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/bass!.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/snaph01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/breath01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/hit02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/metronome01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/electric_ping01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/hit01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/metronome02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/dong03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/metalish_dong01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/dong02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/buzz!.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/raving_crowd01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/misc/dong01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/break03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/rave_snare01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/jungle01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/electro_beat01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/rave_kick02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/909beat01.ogg",
- "mmp/instruments/lmms/samples/beats/rave_kick01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/house_loop01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/rave_hihat01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/break02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/rave_hihat02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/break01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/beats/electro_beat02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/rave_bass04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/matrix1000_pluck01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/rave_bass03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/bass_acid01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/techno_synth01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/bass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/synth_acid02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/bass_hard01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/horror_bass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/bass_acid02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/rave_bass02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/synth_acid01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/bass_punch01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/rave_bass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/basses/bass_hard02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/chorus02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/bell_choir01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/strings01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/space_strings01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/space_strings03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/nord_ambient01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/orion_string01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/heaven_strings01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/korg_poly6_drone01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/bell_choir02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/rave_choir01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/space_strings02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/juno_pad01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/stringsnpads/chorus01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist7.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technobass.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/moog.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/smooth_inv_saw_dist.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/vowel_a.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/roundsaw.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/additive2.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/smooth_inv_saw.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist9.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technosynth1.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technosynth5.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/harmonics.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/smooth_inv_saw2.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist2.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist5.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/sine_dist.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technosynth3.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/micro.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technosynth6.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technosynth2.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist6.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist3.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/low_sine.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/saw+sine.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist4.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/additive.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/bunglist8.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/vowel_u.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/roundbass.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/shapes/technosynth4.wav",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_quarter.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/modsqr.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_triplet_quarter.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_invsine.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_invsinehalf.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_addsyn.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_sharp.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_triplet_half_2.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/saw1.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_rad.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_sawsine.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_sawdecay_quarter.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_noisy.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_hexagon.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/saw2.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/analogsqr.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_invsineabs.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_triplet_half.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/sinesaw.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/fmsaw1.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_sinedecay_quarter.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/10saw.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/fmsine2.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/10tri.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_whole_2.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/10sine.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_angrysaw.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/w2_w-wave.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/10sqr.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/halfsine.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/fmsine.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/impulse.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/waveforms/lfo_trancegate_whole.flac",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/techno_synth04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/tb303_01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/techno_synth01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/techno_synth02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/techno_bass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/techno_synth03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/rave_bass02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/briff01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/rave_bass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/bassloops/techno_bass02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/latin/latin_brass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/latin/latin_guitar03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/latin/latin_guitar02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/latin/latin_guitar01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_opened03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_long01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/clap02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_hardcore01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_opened02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_muffled02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/nasty_bass01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_closed05.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom05.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_hiphop01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/clav02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/nasty_snare01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_hiphop02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_hiphop01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/clap01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/zap03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/bassdrum_acoustic02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom_low01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_short01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/bassdrum03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/bassdrum04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/bassdrum01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_harsh01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/shaker03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom_mid01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_muffled01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_electro01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/crash02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/sidestick01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_closed03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_acoustic01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_closed01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/shaker02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/nasty_rim01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/wood01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/crash01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_opened01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/ride02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/ride01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/bassdrum02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/zap02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare06.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/zap01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/rim01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_foot_pedal01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/clav01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/clap04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_soft02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare07.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/clap03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_hard01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare_rim01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/shaker01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_closed04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/snare05.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/bassdrum_acoustic01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_soft01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/hihat_closed02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/kick_distorted01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/drums/tom_hi01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/flute01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/e_organ01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/trumpet01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/violin_fingered01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/e_piano_accord02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/steel_guitar_heavy_distorted01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/church_organ04.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/steel_guitar_medium_distorted01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/violin_double_stop01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/steel_guitar_slight_distorted01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/church_organ01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/violin_pizzicato01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/bassslap01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/harpsichord01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/piano02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/church_organ03.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/cello01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/bassslap02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/church_organ02.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/e_piano_accord01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/piano01.ogg",
- "/nethome/jotachina/projetos/mmpSearch/mmp/instruments/lmms/samples/instruments/steel_guitar01.ogg"
-]
\ No newline at end of file
diff --git a/_includes/sidebar.html b/_includes/sidebar.html
index c7ea55f..a15e2ef 100644
--- a/_includes/sidebar.html
+++ b/_includes/sidebar.html
@@ -7,7 +7,8 @@
📁 Projetos por tipo de track
🎧 Beats Disponíveis
🎼 Projetos
- 🔎 Buscas
+ 🔎 Buscas ´
+ 🧠 Crie seu projeto
ℹ️ Sobre
diff --git a/_includes/sidebar_home.html b/_includes/sidebar_home.html
index 39682e5..bdda058 100644
--- a/_includes/sidebar_home.html
+++ b/_includes/sidebar_home.html
@@ -7,6 +7,7 @@
🎧 Beats Disponíveis
🎼 Projetos Disponíveis
🔎 Buscas
+ 🧠 Crie seu projeto
ℹ️ Sobre
diff --git a/_layouts/projetos.html b/_layouts/projetos.html
index f86a443..a40af5f 100644
--- a/_layouts/projetos.html
+++ b/_layouts/projetos.html
@@ -119,8 +119,8 @@ title: "{{ page.file }}"
-
-
+
+
Seu navegador não suporta o elemento audio.
diff --git a/assets/css/sidebar.css b/assets/css/sidebar.css
index 8eb4d39..67d7608 100644
--- a/assets/css/sidebar.css
+++ b/assets/css/sidebar.css
@@ -6,7 +6,7 @@
background-color: #f4f4f4;
padding: 1rem;
border-radius: 8px;
- box-shadow: 0 2px 5px rgba(0,0,0,0.1);
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
max-width: 100%;
box-sizing: border-box;
}
@@ -40,4 +40,3 @@
padding: 0.3rem 0.6rem;
}
}
-
diff --git a/assets/css/sidebar_home.css b/assets/css/sidebar_home.css
index e7f1d90..19de719 100644
--- a/assets/css/sidebar_home.css
+++ b/assets/css/sidebar_home.css
@@ -1,33 +1,32 @@
.sidebar-center {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background-color: #f4f4f4;
- padding: 2rem 1.5rem;
- border-radius: 12px;
- box-shadow: 0 0 10px rgba(0,0,0,0.1);
- z-index: 1000;
- }
-
- .submenu {
- display: flex;
- flex-direction: column;
- gap: 1rem;
- align-items: center;
- }
-
- .submenu a {
- text-decoration: none;
- color: #333;
- font-weight: 500;
- padding: 0.5rem 1rem;
- border-radius: 6px;
- transition: background 0.2s;
- white-space: nowrap;
- }
-
- .submenu a:hover {
- background-color: #e0e0e0;
- }
-
\ No newline at end of file
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background-color: #f4f4f4;
+ padding: 2rem 1.5rem;
+ border-radius: 12px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ z-index: 1000;
+}
+
+.submenu {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ align-items: center;
+}
+
+.submenu a {
+ text-decoration: none;
+ color: #333;
+ font-weight: 500;
+ padding: 0.5rem 1rem;
+ border-radius: 6px;
+ transition: background 0.2s;
+ white-space: nowrap;
+}
+
+.submenu a:hover {
+ background-color: #e0e0e0;
+}
diff --git a/assets/css/style.css b/assets/css/style.css
new file mode 100644
index 0000000..f261937
--- /dev/null
+++ b/assets/css/style.css
@@ -0,0 +1,703 @@
+/* =============================================== */
+/* VÁRIAVEIS GLOBAIS (ROOT)
+/* =============================================== */
+:root {
+ --bg-body: #2d3035;
+ --bg-toolbar: #3b3f45;
+ --bg-editor: #33373d;
+ --border-color: #232529;
+ --text-light: #c0c0c0;
+ --text-dark: #888;
+ --accent-green: #2ecc71;
+ --accent-red: #d9534f;
+}
+
+/* =============================================== */
+/* ESTILOS GLOBAIS E LAYOUT PRINCIPAL
+/* =============================================== */
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ background-color: var(--bg-body);
+ color: var(--text-light);
+ padding-left: 300px;
+ transition: padding-left .3s ease;
+}
+
+body.sidebar-hidden {
+ padding-left: 0;
+}
+
+body.knob-dragging {
+ cursor: ns-resize;
+}
+
+.main-content {
+ padding: 2rem;
+}
+
+/* =============================================== */
+/* BARRA LATERAL (SAMPLE BROWSER)
+/* =============================================== */
+.sample-browser {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 300px;
+ height: 100vh;
+ background-color: var(--bg-toolbar);
+ border-right: 2px solid var(--border-color);
+ z-index: 1500;
+ display: flex;
+ flex-direction: column;
+ transform: translateX(0);
+ transition: transform .3s ease;
+}
+
+body.sidebar-hidden .sample-browser {
+ transform: translateX(-100%);
+}
+
+.browser-header {
+ padding: 15px;
+ background-color: #2a2c30;
+ border-bottom: 2px solid var(--border-color);
+ text-align: center;
+ font-weight: bold;
+ color: var(--text-light);
+}
+
+.browser-content {
+ flex-grow: 1;
+ overflow-y: auto;
+ padding: 10px;
+}
+
+.browser-content ul {
+ list-style: none;
+ padding-left: 15px;
+}
+
+.browser-content li {
+ padding: 5px;
+ cursor: pointer;
+ border-radius: 3px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ user-select: none;
+}
+
+.browser-content li:hover {
+ background-color: var(--bg-editor);
+}
+
+.browser-content li i {
+ margin-right: 8px;
+ width: 12px;
+ color: var(--text-dark);
+ transition: transform .2s;
+}
+
+.browser-content li.directory > ul {
+ display: none;
+}
+
+.browser-content li.directory.open > ul {
+ display: block;
+}
+
+.browser-content li.directory.open > .fa-folder {
+ transform: rotate(90deg);
+}
+
+#sidebar-toggle {
+ position: fixed;
+ top: 60px;
+ left: 305px;
+ z-index: 1400;
+ background-color: var(--bg-toolbar);
+ border: 1px solid var(--border-color);
+ color: var(--text-light);
+ width: 25px;
+ height: 40px;
+ cursor: pointer;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ transition: left .3s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+body.sidebar-hidden #sidebar-toggle {
+ left: 5px;
+}
+
+/* =============================================== */
+/* BARRA DE FERRAMENTAS GLOBAL
+/* =============================================== */
+.global-toolbar {
+ padding: 8px 15px;
+ position: fixed;
+ top: 0;
+ /* Removido width 100% para se adaptar ao padding do body */
+ left: 300px;
+ right: 0;
+ z-index: 1000;
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ background-color: var(--bg-toolbar);
+ border-bottom: 2px solid var(--border-color);
+ transition: left .3s ease;
+}
+
+body.sidebar-hidden .global-toolbar {
+ left: 0;
+}
+
+
+/* =============================================== */
+/* EDITOR DE BATIDAS (BEAT EDITOR)
+/* =============================================== */
+.beat-editor {
+ background-color: var(--bg-body);
+ border: 1px solid var(--border-color);
+ width: 100%;
+ max-width: 900px;
+ margin: auto;
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .3);
+ border-radius: 4px;
+ overflow: hidden;
+}
+
+.editor-header {
+ background-color: var(--bg-toolbar);
+ padding: 4px 10px;
+ font-size: .8rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ border-bottom: 1px solid var(--border-color);
+}
+
+.window-controls i {
+ margin-left: 12px;
+ cursor: pointer;
+}
+
+.editor-toolbar {
+ background-color: var(--bg-toolbar);
+ padding: 5px 10px;
+ display: flex;
+ align-items: center;
+ gap: 15px;
+ border-bottom: 2px solid var(--border-color);
+}
+
+.editor-toolbar i {
+ cursor: pointer;
+ padding: 5px;
+ border-radius: 3px;
+}
+
+.editor-toolbar i.enabled {
+ background-color: var(--bg-body);
+ box-shadow: inset 0 0 2px #000;
+}
+
+.pattern-selector {
+ background-color: var(--bg-body);
+ padding: 5px 15px;
+ border: 1px solid var(--border-color);
+ flex-grow: 1;
+ font-size: .9rem;
+ border-radius: 2px;
+}
+
+/* =============================================== */
+/* FAIXAS (TRACK LANES) E SEQUENCIADOR
+/* =============================================== */
+.track-lane {
+ display: flex;
+ align-items: center;
+ padding: 8px 10px;
+ background-color: var(--bg-editor);
+ border: 2px dashed transparent;
+ transition: border-color 0.2s;
+}
+
+.track-lane.drag-over {
+ border-color: var(--accent-green);
+}
+
+.track-info {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ width: 180px;
+ flex-shrink: 0;
+}
+
+.track-info .fa-gear {
+ font-size: 1.2rem;
+ cursor: pointer;
+}
+
+.track-mute {
+ width: 25px;
+ height: 12px;
+ background-color: var(--accent-green);
+ border-radius: 6px;
+ cursor: pointer;
+ border: 1px solid var(--border-color);
+ box-shadow: inset 0 0 2px #000;
+}
+
+.track-name {
+ color: var(--accent-red);
+ font-weight: 700;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.track-controls {
+ display: flex;
+ gap: 5px;
+ margin: 0 10px;
+ padding-left: 10px;
+ border-left: 1px solid var(--bg-toolbar);
+}
+
+.knob-container {
+ text-align: center;
+ font-size: .7rem;
+ color: var(--text-dark);
+}
+
+.knob {
+ width: 28px;
+ height: 28px;
+ background-color: var(--bg-toolbar);
+ border-radius: 50%;
+ border: 1px solid var(--border-color);
+ margin-bottom: 2px;
+ cursor: grab;
+ box-shadow: inset 0 0 4px #222;
+ position: relative;
+}
+
+.knob:active {
+ cursor: grabbing;
+}
+
+.knob-indicator {
+ width: 2px;
+ height: 8px;
+ background-color: var(--text-light);
+ position: absolute;
+ top: 2px;
+ left: 50%;
+ transform-origin: bottom center;
+ transform: translateX(-50%) rotate(0deg);
+ border-radius: 1px;
+}
+
+.step-sequencer {
+ display: flex;
+ flex-grow: 1;
+ gap: 4px;
+ overflow-x: auto;
+ padding-bottom: 8px;
+}
+
+.step-sequencer::-webkit-scrollbar {
+ height: 8px;
+}
+
+.step-sequencer::-webkit-scrollbar-track {
+ background: var(--border-color);
+ border-radius: 4px;
+}
+
+.step-sequencer::-webkit-scrollbar-thumb {
+ background: var(--bg-toolbar);
+ border-radius: 4px;
+}
+
+.step-sequencer::-webkit-scrollbar-thumb:hover {
+ background: #555;
+}
+
+.step-wrapper {
+ position: relative;
+}
+
+.step-marker {
+ position: absolute;
+ top: -16px;
+ left: 1px;
+ font-size: .6rem;
+ color: var(--text-dark);
+}
+
+.step {
+ width: 28px;
+ aspect-ratio: 1 / 1;
+ background-color: #2a2a2a;
+ border: 1px solid #4a4a4a;
+ border-radius: 2px;
+ cursor: pointer;
+ transition: background-color .1s, transform 0.1s;
+ flex-shrink: 0; /* Impede que os steps encolham */
+}
+
+.step-dark {
+ background-color: #1e1e1e;
+}
+
+.step:hover {
+ background-color: #555;
+ border-color: #888;
+}
+
+.step.active {
+ background-color: var(--accent-green);
+ border: 1px solid #fff;
+ box-shadow: 0 0 8px var(--accent-green);
+}
+
+.step.playing {
+ transform: scale(1.1);
+ box-shadow: inset 0 0 8px rgba(255, 255, 255, 0.8);
+}
+
+/* =============================================== */
+/* CONTROLES E INPUTS
+/* =============================================== */
+.interactive-input-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+}
+
+.compasso-group {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.value-input {
+ background: 0 0;
+ border: 0;
+ outline: 0;
+ color: var(--accent-green);
+ font-weight: 700;
+ font-size: 1.4rem;
+ font-family: Courier New, Courier, monospace;
+ text-align: center;
+ padding: 0;
+ width: 55px;
+}
+
+.compasso-input {
+ width: 25px;
+}
+
+.compasso-separator {
+ color: var(--accent-green);
+ font-weight: 700;
+ font-size: 1.4rem;
+ font-family: Courier New, Courier, monospace;
+ margin: 0 2px;
+}
+
+.value-input::-webkit-outer-spin-button,
+.value-input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.value-input[type=number] {
+ -moz-appearance: textfield;
+}
+
+.adjust-btn {
+ background: 0 0;
+ border: 0;
+ color: var(--text-dark);
+ font-size: 1rem;
+ font-weight: 700;
+ cursor: pointer;
+ padding: 0 5px;
+ transition: color .2s;
+ line-height: 1;
+}
+
+.adjust-btn:hover {
+ color: #fff;
+}
+
+.control-group {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+ padding: 0 10px;
+}
+
+.control-group i {
+ font-size: 1.2rem;
+ cursor: pointer;
+ color: var(--text-light);
+ transition: color .2s;
+}
+
+.control-group i:hover {
+ color: #fff;
+}
+
+.fa-play,
+.fa-pause {
+ color: var(--accent-green) !important;
+}
+
+.divider {
+ width: 1px;
+ height: 25px;
+ background-color: var(--border-color);
+}
+
+.info-display-group {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+}
+
+.info-display {
+ background-color: #1a1c1e;
+ padding: 5px 8px;
+ border-radius: 3px;
+ text-align: center;
+}
+
+.info-display .label {
+ color: var(--text-dark);
+ font-size: .6rem;
+ text-transform: uppercase;
+}
+
+.spacer {
+ flex-grow: 1;
+}
+
+#metronome-btn {
+ background: 0 0;
+ border: 1px solid var(--text-dark);
+ color: var(--accent-green);
+ font-family: inherit;
+ font-weight: 700;
+ font-size: .8rem;
+ padding: 5px 10px;
+ border-radius: 3px;
+ cursor: pointer;
+ transition: all .2s;
+}
+
+#metronome-btn:hover {
+ border-color: var(--text-light);
+ background-color: var(--bg-editor);
+}
+
+#metronome-btn.active {
+ background-color: var(--accent-green);
+ color: var(--bg-body);
+ border-color: var(--accent-green);
+}
+
+/* =============================================== */
+/* MODAL (CAIXA DE DIÁLOGO)
+/* =============================================== */
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.7);
+ z-index: 2000;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ visibility: hidden;
+ opacity: 0;
+ transition: visibility 0s 0.3s, opacity 0.3s;
+}
+
+.modal-overlay.visible {
+ visibility: visible;
+ opacity: 1;
+ transition: visibility 0s, opacity 0.3s;
+}
+
+.modal-content {
+ background-color: var(--bg-body);
+ padding: 1.5rem 2rem;
+ border-radius: 6px;
+ border: 1px solid var(--border-color);
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
+ width: 100%;
+ max-width: 500px;
+ position: relative;
+}
+
+.modal-close {
+ position: absolute;
+ top: 10px;
+ right: 15px;
+ font-size: 1.5rem;
+ color: var(--text-dark);
+ cursor: pointer;
+ border: none;
+ background: none;
+}
+
+.modal-close:hover {
+ color: var(--text-light);
+}
+
+.modal-title {
+ margin-top: 0;
+ margin-bottom: 1.5rem;
+ color: var(--text-light);
+ text-align: center;
+}
+
+.modal-section {
+ margin-bottom: 1.5rem;
+}
+
+.modal-section h3 {
+ margin-top: 0;
+ margin-bottom: 0.8rem;
+ border-bottom: 1px solid var(--bg-toolbar);
+ padding-bottom: 0.5rem;
+}
+
+.modal-button {
+ background-color: var(--bg-toolbar);
+ color: var(--text-light);
+ border: 1px solid var(--border-color);
+ padding: 0.8rem 1.5rem;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 1rem;
+ transition: background-color 0.2s, border-color 0.2s;
+ width: 100%;
+}
+
+.modal-button:hover {
+ background-color: #4a4f57;
+ border-color: #333;
+}
+
+#server-projects-list .project-item {
+ background-color: var(--bg-editor);
+ padding: 10px 15px;
+ border-radius: 4px;
+ margin-bottom: 8px;
+ cursor: pointer;
+ transition: background-color 0.2s;
+}
+
+#server-projects-list .project-item:hover {
+ background-color: var(--bg-body);
+ color: #fff;
+}
+
+
+/* =============================================== */
+/* ESTILOS RESPONSIVOS
+/* =============================================== */
+
+/* Para telas menores como laptops pequenos e tablets grandes */
+@media (max-width: 992px) {
+ .main-content {
+ padding: 1.5rem; /* Reduz o padding */
+ }
+
+ .beat-editor {
+ max-width: 100%; /* Permite que o editor use mais espaço */
+ }
+}
+
+
+/* Para tablets e celulares */
+@media (max-width: 768px) {
+ body {
+ padding-left: 0 !important; /* Remove o padding fixo, !important para garantir */
+ }
+
+ .main-content {
+ padding: 1rem;
+ }
+
+ /* A sidebar agora se sobrepõe ao conteúdo e fica escondida por padrão */
+ .sample-browser {
+ transform: translateX(-100%);
+ width: 280px; /* Pode diminuir um pouco a largura */
+ }
+
+ /* Quando a sidebar for aberta, ela volta a posição original */
+ body:not(.sidebar-hidden) .sample-browser {
+ transform: translateX(0);
+ }
+
+ #sidebar-toggle {
+ left: 5px; /* Posição fixa do botão */
+ }
+
+ /* A toolbar global agora ocupa 100% da largura */
+ .global-toolbar {
+ left: 0;
+ padding-left: 45px; /* Espaço para o botão do menu */
+ }
+
+ /* Quebra a linha dos itens da toolbar se não couberem */
+ .editor-toolbar,
+ .control-group {
+ flex-wrap: wrap;
+ gap: 10px;
+ }
+
+ /* Reorganiza a track para um layout vertical */
+ .track-lane {
+ flex-direction: column;
+ align-items: stretch; /* Itens ocupam 100% da largura */
+ gap: 15px;
+ padding: 15px;
+ }
+
+ .track-info,
+ .track-controls {
+ width: 100%;
+ }
+
+ .track-controls {
+ border-left: none;
+ padding-left: 0;
+ justify-content: space-around; /* Distribui melhor os knobs */
+ }
+
+ .step-sequencer {
+ width: 100%;
+ }
+
+ /* Ajusta o modal para telas pequenas */
+ .modal-content {
+ max-width: 90vw;
+ padding: 1.5rem 1rem;
+ }
+}
\ No newline at end of file
diff --git a/assets/js/creations/audio.js b/assets/js/creations/audio.js
new file mode 100644
index 0000000..9cdd9c9
--- /dev/null
+++ b/assets/js/creations/audio.js
@@ -0,0 +1,134 @@
+//TODO ver Tone.js
+
+// js/audio.js
+import { appState } from "./state.js";
+import { highlightStep } from "./ui.js";
+import { getTotalSteps } from "./utils.js";
+
+let audioContext;
+let mainGainNode;
+
+export function getAudioContext() {
+ return audioContext;
+}
+export function getMainGainNode() {
+ return mainGainNode;
+}
+
+export function initializeAudioContext() {
+ if (!audioContext) {
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ mainGainNode = audioContext.createGain();
+ mainGainNode.connect(audioContext.destination);
+ }
+ if (audioContext.state === "suspended") {
+ audioContext.resume();
+ }
+}
+
+export function playMetronomeSound(isDownbeat) {
+ initializeAudioContext();
+ const oscillator = audioContext.createOscillator();
+ const gainNode = audioContext.createGain();
+ const frequency = isDownbeat ? 1000 : 800;
+ oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
+ oscillator.type = "sine";
+ gainNode.gain.setValueAtTime(1, audioContext.currentTime);
+ gainNode.gain.exponentialRampToValueAtTime(
+ 0.00001,
+ audioContext.currentTime + 0.05
+ );
+ oscillator.connect(gainNode);
+ gainNode.connect(audioContext.destination);
+ oscillator.start(audioContext.currentTime);
+ oscillator.stop(audioContext.currentTime + 0.05);
+}
+
+export function playSample(filePath, trackId) {
+ initializeAudioContext();
+ if (!filePath) return;
+
+ const track = trackId ? appState.tracks.find((t) => t.id == trackId) : null;
+ const audio = new Audio(filePath);
+ const source = audioContext.createMediaElementSource(audio);
+
+ if (track && track.gainNode) {
+ source.connect(track.gainNode);
+ } else {
+ source.connect(mainGainNode);
+ }
+
+ audio.play();
+}
+
+function tick() {
+ const totalSteps = getTotalSteps();
+ if (totalSteps === 0) {
+ stopPlayback();
+ return;
+ }
+ const lastStepIndex =
+ appState.currentStep === 0 ? totalSteps - 1 : appState.currentStep - 1;
+ highlightStep(lastStepIndex, false);
+
+ if (appState.metronomeEnabled) {
+ const noteValue =
+ parseInt(document.getElementById("compasso-b-input").value, 10) || 4;
+ const stepsPerBeat = 16 / noteValue;
+ if (appState.currentStep % stepsPerBeat === 0) {
+ playMetronomeSound(appState.currentStep === 0);
+ }
+ }
+
+ appState.tracks.forEach((track) => {
+ if (track.steps[appState.currentStep] && track.samplePath) {
+ playSample(track.samplePath, track.id);
+ }
+ });
+
+ highlightStep(appState.currentStep, true);
+ appState.currentStep = (appState.currentStep + 1) % totalSteps;
+}
+
+export function startPlayback() {
+ if (appState.isPlaying || appState.tracks.length === 0) return;
+ initializeAudioContext();
+ const bpm = parseInt(document.getElementById("bpm-input").value, 10) || 120;
+ const stepInterval = (60 * 1000) / (bpm * 4);
+
+ if (appState.playbackIntervalId) clearInterval(appState.playbackIntervalId);
+
+ appState.isPlaying = true;
+ document.getElementById("play-btn").classList.remove("fa-play");
+ document.getElementById("play-btn").classList.add("fa-pause");
+
+ tick();
+ appState.playbackIntervalId = setInterval(tick, stepInterval);
+}
+
+export function stopPlayback() {
+ clearInterval(appState.playbackIntervalId);
+ appState.playbackIntervalId = null;
+ appState.isPlaying = false;
+ highlightStep(appState.currentStep - 1, false);
+ appState.currentStep = 0;
+ document.getElementById("play-btn").classList.remove("fa-pause");
+ document.getElementById("play-btn").classList.add("fa-play");
+}
+
+export function rewindPlayback() {
+ appState.currentStep = 0;
+ if (!appState.isPlaying) {
+ document
+ .querySelectorAll(".step.playing")
+ .forEach((s) => s.classList.remove("playing"));
+ }
+}
+
+export function togglePlayback() {
+ if (appState.isPlaying) {
+ stopPlayback();
+ } else {
+ startPlayback();
+ }
+}
diff --git a/assets/js/creations/config.js b/assets/js/creations/config.js
new file mode 100644
index 0000000..4b0ef63
--- /dev/null
+++ b/assets/js/creations/config.js
@@ -0,0 +1,9 @@
+// js/config.js
+
+// Constantes usadas para o cálculo de posição de notas no arquivo .mmp
+export const TICKS_PER_BAR = 192;
+export const NOTE_LENGTH = 12;
+
+// Constantes para os valores padrão dos knobs
+export const DEFAULT_VOLUME = 0.8;
+export const DEFAULT_PAN = 0.0;
diff --git a/assets/js/creations/file.js b/assets/js/creations/file.js
new file mode 100644
index 0000000..d9d924d
--- /dev/null
+++ b/assets/js/creations/file.js
@@ -0,0 +1,243 @@
+// js/file.js
+import { appState } from "./state.js";
+import { getTotalSteps } from "./utils.js";
+import { renderApp } from "./ui.js";
+import { NOTE_LENGTH, TICKS_PER_BAR } from "./config.js";
+import {
+ initializeAudioContext,
+ getAudioContext,
+ getMainGainNode,
+} from "./audio.js";
+
+export async function handleFileLoad(file) {
+ let xmlContent = "";
+ try {
+ if (file.name.toLowerCase().endsWith(".mmpz")) {
+ const jszip = new JSZip();
+ const zip = await jszip.loadAsync(file);
+ const projectFile = Object.keys(zip.files).find((name) =>
+ name.toLowerCase().endsWith(".mmp")
+ );
+ if (!projectFile)
+ throw new Error(
+ "Não foi possível encontrar um arquivo .mmp dentro do .mmpz"
+ );
+ xmlContent = await zip.files[projectFile].async("string");
+ } else {
+ xmlContent = await file.text();
+ }
+ parseMmpContent(xmlContent);
+ } catch (error) {
+ console.error("Erro ao carregar o projeto:", error);
+ alert(`Erro ao carregar projeto: ${error.message}`);
+ }
+}
+
+export function parseMmpContent(xmlString) {
+ initializeAudioContext();
+ const parser = new DOMParser();
+ const xmlDoc = parser.parseFromString(xmlString, "application/xml");
+
+ appState.originalXmlDoc = xmlDoc;
+ const newTracks = [];
+
+ const head = xmlDoc.querySelector("head");
+ if (head) {
+ document.getElementById("bpm-input").value =
+ head.getAttribute("bpm") || 140;
+ document.getElementById("compasso-a-input").value =
+ head.getAttribute("timesig_numerator") || 4;
+ document.getElementById("compasso-b-input").value =
+ head.getAttribute("timesig_denominator") || 4;
+ }
+ const sampleTrackElements = xmlDoc.querySelectorAll(
+ 'instrument[name="audiofileprocessor"]'
+ );
+ sampleTrackElements.forEach((instrumentNode) => {
+ const afpNode = instrumentNode.querySelector("audiofileprocessor");
+ const instrumentTrackNode = instrumentNode.parentElement;
+ const trackNode = instrumentTrackNode.parentElement;
+ if (!afpNode || !instrumentTrackNode || !trackNode) return;
+
+ const audioContext = getAudioContext();
+ const mainGainNode = getMainGainNode();
+ const totalSteps = parseInt(
+ trackNode.querySelector("pattern")?.getAttribute("steps") ||
+ getTotalSteps(),
+ 10
+ );
+ const newSteps = new Array(totalSteps).fill(false);
+ const ticksPerStep = totalSteps > 0 ? TICKS_PER_BAR / totalSteps : 0;
+
+ trackNode.querySelectorAll("pattern note").forEach((noteNode) => {
+ const pos = parseInt(noteNode.getAttribute("pos"), 10);
+ const stepIndex = Math.round(pos / ticksPerStep);
+ if (stepIndex < totalSteps) {
+ newSteps[stepIndex] = true;
+ }
+ });
+ const newTrack = {
+ id: Date.now() + Math.random(),
+ name:
+ afpNode.getAttribute("src").split("/").pop() ||
+ trackNode.getAttribute("name"),
+ samplePath: `samples/${afpNode.getAttribute("src")}`,
+ steps: newSteps,
+ volume: parseFloat(instrumentTrackNode.getAttribute("vol")) / 100,
+ pan: parseFloat(instrumentTrackNode.getAttribute("pan")) / 100,
+ gainNode: audioContext.createGain(),
+ pannerNode: audioContext.createStereoPanner(),
+ };
+ newTrack.gainNode.connect(newTrack.pannerNode);
+ newTrack.pannerNode.connect(mainGainNode);
+ newTrack.gainNode.gain.value = newTrack.volume;
+ newTrack.pannerNode.pan.value = newTrack.pan;
+ newTracks.push(newTrack);
+ });
+ appState.tracks = newTracks;
+ renderApp();
+ console.log("Projeto carregado com sucesso!", appState);
+}
+
+export function generateMmpFile() {
+ if (appState.originalXmlDoc) {
+ modifyAndSaveExistingMmp();
+ } else {
+ generateNewMmp();
+ }
+}
+
+function generateNewMmp() {
+ console.log("Gerando novo arquivo .mmp do zero...");
+ const bpm = document.getElementById("bpm-input").value;
+ const sig_num = document.getElementById("compasso-a-input").value;
+ const sig_den = document.getElementById("compasso-b-input").value;
+ const tracksXml = appState.tracks
+ .map((track) => createTrackXml(track))
+ .join("");
+
+ const mmpContent = `
+
+
+
+
+
+
+
+
+ ${tracksXml}
+
+
+
+
+
+
+
+
+
+Feito com MMPCreator no https://alice.ufsj.edu.br/MMPSearch/creator
+]]>
+
+`;
+ downloadFile(mmpContent, "novo_projeto.mmp");
+}
+
+function modifyAndSaveExistingMmp() {
+ console.log("Modificando arquivo .mmp existente...");
+ const xmlDoc = appState.originalXmlDoc.cloneNode(true);
+ const head = xmlDoc.querySelector("head");
+ if (head) {
+ head.setAttribute("bpm", document.getElementById("bpm-input").value);
+ head.setAttribute(
+ "timesig_numerator",
+ document.getElementById("compasso-a-input").value
+ );
+ head.setAttribute(
+ "timesig_denominator",
+ document.getElementById("compasso-b-input").value
+ );
+ }
+ const bbTrackContainer = xmlDoc.querySelector("bbtrack > trackcontainer");
+ if (bbTrackContainer) {
+ const oldSampleTracks = bbTrackContainer.querySelectorAll(
+ 'instrument[name="audiofileprocessor"]'
+ );
+ oldSampleTracks.forEach((node) => node.closest("track").remove());
+ const tracksXml = appState.tracks
+ .map((track) => createTrackXml(track))
+ .join("");
+ const tempDoc = new DOMParser().parseFromString(
+ `${tracksXml} `,
+ "application/xml"
+ );
+ Array.from(tempDoc.documentElement.children).forEach((newTrackNode) => {
+ bbTrackContainer.appendChild(newTrackNode);
+ });
+ }
+
+ const serializer = new XMLSerializer();
+ const mmpContent = serializer.serializeToString(xmlDoc);
+ downloadFile(mmpContent, "projeto_editado.mmp");
+}
+
+function createTrackXml(track) {
+ if (!track.samplePath) return "";
+ const totalSteps = track.steps.length || getTotalSteps();
+ const ticksPerStep = totalSteps > 0 ? TICKS_PER_BAR / totalSteps : 0;
+ const lmmsVolume = Math.round(track.volume * 100);
+ const lmmsPan = Math.round(track.pan * 100);
+ const sampleSrc = track.samplePath.replace("samples/", "");
+ const notesXml = track.steps
+ .map((isActive, index) => {
+ if (isActive) {
+ const notePos = Math.round(index * ticksPerStep);
+ return ` `;
+ }
+ return "";
+ })
+ .join("\n ");
+ return `
+
+
+
+
+
+
+
+
+ ${notesXml}
+
+ `;
+}
+
+function downloadFile(content, fileName) {
+ const blob = new Blob([content], { type: "application/xml;charset=utf-8" });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement("a");
+ a.href = url;
+ a.download = fileName;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ URL.revokeObjectURL(url);
+}
+
+// (ALTERADO) Adiciona export na frente da função
+export async function loadProjectFromServer(fileName) {
+ try {
+ const response = await fetch(`mmp/${fileName}`);
+ if (!response.ok)
+ throw new Error(`Não foi possível carregar o arquivo ${fileName}`);
+ const xmlContent = await response.text();
+ parseMmpContent(xmlContent);
+ // Retorna true em caso de sucesso
+ return true;
+ } catch (error) {
+ console.error("Erro ao carregar projeto do servidor:", error);
+ alert(`Erro ao carregar projeto: ${error.message}`);
+ // Retorna false em caso de falha
+ return false;
+ }
+}
diff --git a/assets/js/creations/main.js b/assets/js/creations/main.js
new file mode 100644
index 0000000..65634ab
--- /dev/null
+++ b/assets/js/creations/main.js
@@ -0,0 +1,121 @@
+// js/main.js
+import {
+ appState,
+ addTrackToState,
+ removeLastTrackFromState,
+} from "./state.js";
+import {
+ togglePlayback,
+ stopPlayback,
+ rewindPlayback,
+ initializeAudioContext,
+} from "./audio.js";
+import { handleFileLoad, generateMmpFile } from "./file.js";
+import {
+ renderApp,
+ redrawSequencer,
+ loadAndRenderSampleBrowser,
+ showOpenProjectModal,
+ closeOpenProjectModal,
+} from "./ui.js";
+import { adjustValue, enforceNumericInput } from "./utils.js";
+
+// --- INICIALIZAÇÃO E EVENTOS FINAIS ---
+document.addEventListener("DOMContentLoaded", () => {
+ const newProjectBtn = document.getElementById("new-project-btn");
+ const openMmpBtn = document.getElementById("open-mmp-btn");
+ const saveMmpBtn = document.getElementById("save-mmp-btn");
+ const addInstrumentBtn = document.getElementById("add-instrument-btn");
+ const removeInstrumentBtn = document.getElementById("remove-instrument-btn");
+ const playBtn = document.getElementById("play-btn");
+ const stopBtn = document.getElementById("stop-btn");
+ const rewindBtn = document.getElementById("rewind-btn");
+ const metronomeBtn = document.getElementById("metronome-btn");
+ const mmpFileInput = document.getElementById("mmp-file-input");
+ const openProjectModal = document.getElementById("open-project-modal");
+ const openModalCloseBtn = document.getElementById("open-modal-close-btn");
+ const loadFromComputerBtn = document.getElementById("load-from-computer-btn");
+ const sidebarToggle = document.getElementById("sidebar-toggle");
+
+ newProjectBtn.addEventListener("click", () => {
+ if (
+ appState.tracks.length > 0 &&
+ !confirm("Você tem certeza? Alterações não salvas serão perdidas.")
+ )
+ return;
+ Object.assign(appState, {
+ tracks: [],
+ isPlaying: false,
+ playbackIntervalId: null,
+ currentStep: 0,
+ metronomeEnabled: false,
+ originalXmlDoc: null,
+ });
+ renderApp();
+ });
+
+ openMmpBtn.addEventListener("click", showOpenProjectModal);
+ loadFromComputerBtn.addEventListener("click", () => mmpFileInput.click());
+ mmpFileInput.addEventListener("change", (event) => {
+ const file = event.target.files[0];
+ if (file) {
+ handleFileLoad(file);
+ closeOpenProjectModal();
+ }
+ });
+ saveMmpBtn.addEventListener("click", generateMmpFile);
+ addInstrumentBtn.addEventListener("click", addTrackToState);
+ removeInstrumentBtn.addEventListener("click", removeLastTrackFromState);
+ playBtn.addEventListener("click", togglePlayback);
+ stopBtn.addEventListener("click", stopPlayback);
+ rewindBtn.addEventListener("click", rewindPlayback);
+ metronomeBtn.addEventListener("click", () => {
+ initializeAudioContext();
+ appState.metronomeEnabled = !appState.metronomeEnabled;
+ metronomeBtn.classList.toggle("active", appState.metronomeEnabled);
+ });
+ openModalCloseBtn.addEventListener("click", closeOpenProjectModal);
+ openProjectModal.addEventListener("click", (e) => {
+ if (e.target === openProjectModal) closeOpenProjectModal();
+ });
+ sidebarToggle.addEventListener("click", () => {
+ document.body.classList.toggle("sidebar-hidden");
+ const icon = sidebarToggle.querySelector("i");
+ icon.className = document.body.classList.contains("sidebar-hidden")
+ ? "fa-solid fa-caret-right"
+ : "fa-solid fa-caret-left";
+ });
+
+ const inputs = document.querySelectorAll(".value-input");
+ inputs.forEach((input) => {
+ input.addEventListener("input", (event) => {
+ enforceNumericInput(event);
+ if (appState.isPlaying && event.target.id.startsWith("compasso-")) {
+ stopPlayback();
+ }
+ if (event.target.id.startsWith("compasso-")) {
+ redrawSequencer();
+ }
+ });
+ input.addEventListener("wheel", (event) => {
+ event.preventDefault();
+ const step = event.deltaY < 0 ? 1 : -1;
+ adjustValue(event.target, step);
+ });
+ });
+
+ const buttons = document.querySelectorAll(".adjust-btn");
+ buttons.forEach((button) => {
+ button.addEventListener("click", () => {
+ const targetId = button.dataset.target + "-input";
+ const targetInput = document.getElementById(targetId);
+ if (targetInput) {
+ adjustValue(targetInput, step);
+ }
+ });
+ });
+
+ // Inicia a aplicação
+ loadAndRenderSampleBrowser();
+ renderApp();
+});
diff --git a/assets/js/creations/state.js b/assets/js/creations/state.js
new file mode 100644
index 0000000..c58a477
--- /dev/null
+++ b/assets/js/creations/state.js
@@ -0,0 +1,90 @@
+// js/state.js
+import { DEFAULT_VOLUME, DEFAULT_PAN } from "./config.js";
+import {
+ initializeAudioContext,
+ getAudioContext,
+ getMainGainNode,
+} from "./audio.js";
+import { renderApp } from "./ui.js";
+
+// O "cérebro" da aplicação
+export let appState = {
+ tracks: [],
+ isPlaying: false,
+ playbackIntervalId: null,
+ currentStep: 0,
+ metronomeEnabled: false,
+ originalXmlDoc: null,
+};
+
+export function addTrackToState() {
+ initializeAudioContext();
+ const audioContext = getAudioContext();
+ const mainGainNode = getMainGainNode();
+
+ const newTrack = {
+ id: Date.now(),
+ name: "novo instrumento",
+ samplePath: null,
+ steps: [],
+ volume: DEFAULT_VOLUME,
+ pan: DEFAULT_PAN,
+ gainNode: audioContext.createGain(),
+ pannerNode: audioContext.createStereoPanner(),
+ };
+ newTrack.gainNode.connect(newTrack.pannerNode);
+ newTrack.pannerNode.connect(mainGainNode);
+ newTrack.gainNode.gain.value = newTrack.volume;
+ newTrack.pannerNode.pan.value = newTrack.pan;
+
+ appState.tracks.push(newTrack);
+ renderApp();
+}
+
+export function removeLastTrackFromState() {
+ appState.tracks.pop();
+ renderApp();
+}
+
+export function updateTrackSample(trackId, samplePath) {
+ const track = appState.tracks.find((t) => t.id == trackId);
+ if (track) {
+ track.samplePath = samplePath;
+ track.name = samplePath.split("/").pop();
+ }
+ renderApp();
+}
+
+export function toggleStepState(trackId, stepIndex) {
+ const track = appState.tracks.find((t) => t.id == trackId);
+ if (track) {
+ track.steps[stepIndex] = !track.steps[stepIndex];
+ }
+}
+
+export function updateTrackVolume(trackId, volume) {
+ const track = appState.tracks.find((t) => t.id == trackId);
+ const audioContext = getAudioContext();
+ if (track) {
+ const clampedVolume = Math.max(0, Math.min(1.5, volume));
+ track.volume = clampedVolume;
+ if (track.gainNode) {
+ track.gainNode.gain.setValueAtTime(
+ clampedVolume,
+ audioContext.currentTime
+ );
+ }
+ }
+}
+
+export function updateTrackPan(trackId, pan) {
+ const track = appState.tracks.find((t) => t.id == trackId);
+ const audioContext = getAudioContext();
+ if (track) {
+ const clampedPan = Math.max(-1, Math.min(1, pan));
+ track.pan = clampedPan;
+ if (track.pannerNode) {
+ track.pannerNode.pan.setValueAtTime(clampedPan, audioContext.currentTime);
+ }
+ }
+}
diff --git a/assets/js/creations/ui.js b/assets/js/creations/ui.js
new file mode 100644
index 0000000..3ed6ecd
--- /dev/null
+++ b/assets/js/creations/ui.js
@@ -0,0 +1,319 @@
+// js/ui.js
+import {
+ appState,
+ toggleStepState,
+ updateTrackSample,
+ updateTrackVolume,
+ updateTrackPan,
+} from "./state.js";
+import { playSample } from "./audio.js";
+import { getTotalSteps } from "./utils.js";
+import { loadProjectFromServer } from "./file.js"; // (CORREÇÃO) Importa a função que faltava
+
+// RENDERIZAÇÃO PRINCIPAL
+export function renderApp() {
+ const trackContainer = document.getElementById("track-container");
+ trackContainer.innerHTML = "";
+ appState.tracks.forEach((trackData) => {
+ const trackLane = document.createElement("div");
+ trackLane.className = "track-lane";
+ trackLane.dataset.trackId = trackData.id;
+
+ trackLane.innerHTML = `
+
+
+
+ `;
+
+ trackLane.addEventListener("dragover", (e) => {
+ e.preventDefault();
+ trackLane.classList.add("drag-over");
+ });
+ trackLane.addEventListener("dragleave", () =>
+ trackLane.classList.remove("drag-over")
+ );
+ trackLane.addEventListener("drop", (e) => {
+ e.preventDefault();
+ trackLane.classList.remove("drag-over");
+ const filePath = e.dataTransfer.getData("text/plain");
+ if (filePath) {
+ updateTrackSample(trackData.id, filePath);
+ }
+ });
+
+ trackContainer.appendChild(trackLane);
+
+ const volumeKnob = trackLane.querySelector(".knob[data-control='volume']");
+ addKnobInteraction(volumeKnob);
+ updateKnobVisual(volumeKnob, "volume");
+
+ const panKnob = trackLane.querySelector(".knob[data-control='pan']");
+ addKnobInteraction(panKnob);
+ updateKnobVisual(panKnob, "pan");
+ });
+ redrawSequencer();
+}
+
+export function redrawSequencer() {
+ const beatsPerBar =
+ parseInt(document.getElementById("compasso-a-input").value, 10) || 4;
+ const totalSteps = getTotalSteps();
+ document.querySelectorAll(".step-sequencer").forEach((container) => {
+ const parentTrackElement = container.closest(".track-lane");
+ const trackId = parentTrackElement.dataset.trackId;
+ const trackData = appState.tracks.find((t) => t.id == trackId);
+ if (trackData && trackData.steps.length !== totalSteps) {
+ const newStepsState = new Array(totalSteps).fill(false);
+ for (let i = 0; i < Math.min(trackData.steps.length, totalSteps); i++) {
+ newStepsState[i] = trackData.steps[i];
+ }
+ trackData.steps = newStepsState;
+ }
+ container.innerHTML = "";
+ for (let i = 0; i < totalSteps; i++) {
+ const stepWrapper = document.createElement("div");
+ stepWrapper.className = "step-wrapper";
+ const stepElement = document.createElement("div");
+ stepElement.className = "step";
+ if (trackData && trackData.steps[i] === true) {
+ stepElement.classList.add("active");
+ }
+ stepElement.addEventListener("click", () => {
+ toggleStepState(trackData.id, i);
+ stepElement.classList.toggle("active");
+ if (trackData && trackData.samplePath) {
+ playSample(trackData.samplePath, trackData.id);
+ }
+ });
+ const groupIndex = Math.floor(i / beatsPerBar);
+ if (groupIndex % 2 === 0) {
+ stepElement.classList.add("step-dark");
+ }
+ if (i > 0 && i % beatsPerBar === 0) {
+ const marker = document.createElement("div");
+ marker.className = "step-marker";
+ marker.textContent = i;
+ stepWrapper.appendChild(marker);
+ }
+ stepWrapper.appendChild(stepElement);
+ container.appendChild(stepWrapper);
+ }
+ });
+}
+
+// LÓGICA DE INTERAÇÃO DOS KNOBS
+function addKnobInteraction(knobElement) {
+ const controlType = knobElement.dataset.control;
+ knobElement.addEventListener("mousedown", (e) => {
+ if (e.button === 1) {
+ e.preventDefault();
+ const trackId = knobElement.dataset.trackId;
+ const defaultValue = controlType === "volume" ? 0.8 : 0.0;
+ if (controlType === "volume") {
+ updateTrackVolume(trackId, defaultValue);
+ } else {
+ updateTrackPan(trackId, defaultValue);
+ }
+ }
+ });
+ knobElement.addEventListener("mousedown", (e) => {
+ if (e.button !== 0) return;
+ e.preventDefault();
+ const trackId = knobElement.dataset.trackId;
+ const track = appState.tracks.find((t) => t.id == trackId);
+ if (!track) return;
+ const startY = e.clientY;
+ const startValue = controlType === "volume" ? track.volume : track.pan;
+ document.body.classList.add("knob-dragging");
+ function onMouseMove(moveEvent) {
+ const deltaY = startY - moveEvent.clientY;
+ const sensitivity = controlType === "volume" ? 150 : 200;
+ const newValue = startValue + deltaY / sensitivity;
+ if (controlType === "volume") {
+ updateTrackVolume(trackId, newValue);
+ } else {
+ updateTrackPan(trackId, newValue);
+ }
+ }
+ function onMouseUp() {
+ document.body.classList.remove("knob-dragging");
+ document.removeEventListener("mousemove", onMouseMove);
+ document.removeEventListener("mouseup", onMouseUp);
+ }
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+ });
+ knobElement.addEventListener("wheel", (e) => {
+ e.preventDefault();
+ const trackId = knobElement.dataset.trackId;
+ const track = appState.tracks.find((t) => t.id == trackId);
+ if (!track) return;
+ const step = 0.05;
+ const direction = e.deltaY < 0 ? 1 : -1;
+ if (controlType === "volume") {
+ const newValue = track.volume + direction * step;
+ updateTrackVolume(trackId, newValue);
+ } else {
+ const newValue = track.pan + direction * step;
+ updateTrackPan(trackId, newValue);
+ }
+ });
+}
+
+function updateKnobVisual(knobElement, controlType) {
+ const trackId = knobElement.dataset.trackId;
+ const track = appState.tracks.find((t) => t.id == trackId);
+ if (!track) return;
+ const indicator = knobElement.querySelector(".knob-indicator");
+ if (!indicator) return;
+ const minAngle = -135;
+ const maxAngle = 135;
+ let percentage = 0.5;
+ let title = "";
+ if (controlType === "volume") {
+ const value = track.volume;
+ const clampedValue = Math.max(0, Math.min(1.5, value));
+ percentage = clampedValue / 1.5;
+ title = `Volume: ${Math.round(clampedValue * 100)}%`;
+ } else {
+ const value = track.pan;
+ const clampedValue = Math.max(-1, Math.min(1, value));
+ percentage = (clampedValue + 1) / 2;
+ const panDisplay = Math.round(clampedValue * 100);
+ title = `Pan: ${
+ panDisplay === 0
+ ? "Centro"
+ : panDisplay < 0
+ ? `${-panDisplay} L`
+ : `${panDisplay} R`
+ }`;
+ }
+ const angle = minAngle + percentage * (maxAngle - minAngle);
+ indicator.style.transform = `translateX(-50%) rotate(${angle}deg)`;
+ knobElement.title = title;
+}
+
+export function highlightStep(stepIndex, isActive) {
+ if (stepIndex < 0) return;
+ document.querySelectorAll(".track-lane").forEach((track) => {
+ const stepWrapper = track.querySelector(
+ `.step-sequencer .step-wrapper:nth-child(${stepIndex + 1})`
+ );
+ if (stepWrapper) {
+ const stepElement = stepWrapper.querySelector(".step");
+ if (stepElement) {
+ stepElement.classList.toggle("playing", isActive);
+ }
+ }
+ });
+}
+
+// LÓGICA DA SIDEBAR E MODAL
+export async function loadAndRenderSampleBrowser() {
+ const browserContent = document.getElementById("browser-content");
+ try {
+ const response = await fetch("metadata/samples-manifest.json");
+ if (!response.ok) {
+ throw new Error("Arquivo samples-manifest.json não encontrado.");
+ }
+ const fileTree = await response.json();
+ renderFileTree(fileTree, browserContent, "src/samples");
+ } catch (error) {
+ console.error("Erro ao carregar samples:", error);
+ browserContent.innerHTML = `${error.message}
`;
+ }
+}
+
+function renderFileTree(tree, parentElement, currentPath) {
+ parentElement.innerHTML = "";
+ const ul = document.createElement("ul");
+ const sortedKeys = Object.keys(tree).sort((a, b) => {
+ const aIsFile = tree[a]._isFile;
+ const bIsFile = tree[b]._isFile;
+ if (aIsFile === bIsFile) return a.localeCompare(b);
+ return aIsFile ? 1 : -1;
+ });
+ for (const key of sortedKeys) {
+ const node = tree[key];
+ const li = document.createElement("li");
+ const newPath = `${currentPath}/${key}`;
+ if (node._isFile) {
+ li.innerHTML = ` ${key}`;
+ li.setAttribute("draggable", true);
+ li.addEventListener("click", (e) => {
+ e.stopPropagation();
+ playSample(newPath, null);
+ });
+ li.addEventListener("dragstart", (e) => {
+ e.dataTransfer.setData("text/plain", newPath);
+ e.dataTransfer.effectAllowed = "copy";
+ });
+ ul.appendChild(li);
+ } else {
+ li.className = "directory";
+ li.innerHTML = ` ${key}`;
+ const nestedUl = document.createElement("ul");
+ renderFileTree(node, nestedUl, newPath);
+ li.appendChild(nestedUl);
+ li.addEventListener("click", (e) => {
+ e.stopPropagation();
+ li.classList.toggle("open");
+ });
+ ul.appendChild(li);
+ }
+ }
+ parentElement.appendChild(ul);
+}
+
+export async function showOpenProjectModal() {
+ const openProjectModal = document.getElementById("open-project-modal");
+ const serverProjectsList = document.getElementById("server-projects-list");
+ serverProjectsList.innerHTML = "Carregando...
";
+ openProjectModal.classList.add("visible");
+ try {
+ const response = await fetch("metadata/mmp-manifest.json");
+ if (!response.ok)
+ throw new Error("Arquivo mmp-manifest.json não encontrado.");
+ const projects = await response.json();
+
+ serverProjectsList.innerHTML = "";
+ if (projects.length === 0) {
+ serverProjectsList.innerHTML =
+ 'Nenhum projeto encontrado no servidor.
';
+ }
+
+ projects.forEach((projectName) => {
+ const projectItem = document.createElement("div");
+ projectItem.className = "project-item";
+ projectItem.textContent = projectName;
+ projectItem.addEventListener("click", async () => {
+ const success = await loadProjectFromServer(projectName);
+ if (success) {
+ closeOpenProjectModal();
+ }
+ });
+ serverProjectsList.appendChild(projectItem);
+ });
+ } catch (error) {
+ console.error("Erro ao carregar lista de projetos:", error);
+ serverProjectsList.innerHTML = `${error.message}
`;
+ }
+}
+
+export function closeOpenProjectModal() {
+ const openProjectModal = document.getElementById("open-project-modal");
+ openProjectModal.classList.remove("visible");
+}
diff --git a/assets/js/creations/utils.js b/assets/js/creations/utils.js
new file mode 100644
index 0000000..ca7f2d8
--- /dev/null
+++ b/assets/js/creations/utils.js
@@ -0,0 +1,27 @@
+// js/utils.js
+
+export function getTotalSteps() {
+ const compassoAInput = document.getElementById("compasso-a-input");
+ const compassoBInput = document.getElementById("compasso-b-input");
+ const beatsPerBar = parseInt(compassoAInput.value, 10) || 4;
+ const noteValue = parseInt(compassoBInput.value, 10) || 4;
+ const subdivisions = Math.round(16 / noteValue);
+ return beatsPerBar * subdivisions;
+}
+
+export function enforceNumericInput(event) {
+ event.target.value = event.target.value.replace(/[^0-9]/g, "");
+}
+
+export function adjustValue(inputElement, step) {
+ let currentValue = parseInt(inputElement.value, 10) || 0;
+ let min = parseInt(inputElement.dataset.min, 10);
+ let max = parseInt(inputElement.dataset.max, 10);
+ let newValue = currentValue + step;
+ if (!isNaN(min) && newValue < min) newValue = min;
+ if (!isNaN(max) && newValue > max) newValue = max;
+ inputElement.value = newValue;
+
+ // Dispara um evento 'input' para que outros listeners (como o que redesenha o sequenciador) sejam acionados.
+ inputElement.dispatchEvent(new Event("input", { bubbles: true }));
+}
diff --git a/assets/js/search.js b/assets/js/search.js
index 26b234f..aa74668 100644
--- a/assets/js/search.js
+++ b/assets/js/search.js
@@ -1,108 +1,123 @@
-document.addEventListener("DOMContentLoaded", function() {
- var fileItemsMMP = document.querySelectorAll('#file-list-mmp .file-item');
- var fileItemsWAV = document.querySelectorAll('#file-list-wav .file-wav-item');
+document.addEventListener("DOMContentLoaded", function () {
+ var fileItemsMMP = document.querySelectorAll("#file-list-mmp .file-item");
+ var fileItemsWAV = document.querySelectorAll("#file-list-wav .file-wav-item");
// Função para exibir apenas os arquivos WAV correspondentes aos instrumentos encontrados nos projetos MMP
function showWAVFilesByInstrument(selectedInstrument) {
- fileItemsWAV.forEach(function(item) {
- var fileName = item.getAttribute('data-file').toLowerCase();
+ fileItemsWAV.forEach(function (item) {
+ var fileName = item.getAttribute("data-file").toLowerCase();
if (fileName.includes(selectedInstrument)) {
- item.style.display = 'block';
+ item.style.display = "block";
} else {
- item.style.display = 'none';
+ item.style.display = "none";
}
});
}
// Buscar por instrumento usando o campo de entrada para MMP
- var searchButton = document.getElementById('search-button');
- searchButton.addEventListener('click', function() {
- var searchInput = document.getElementById('instrument-search').value.trim().toLowerCase();
- if (searchInput === '') {
+ var searchButton = document.getElementById("search-button");
+ searchButton.addEventListener("click", function () {
+ var searchInput = document
+ .getElementById("instrument-search")
+ .value.trim()
+ .toLowerCase();
+ if (searchInput === "") {
resetSearch();
return;
}
- fileItemsMMP.forEach(function(item) {
- var instrumentsList = item.querySelectorAll('.instrument-list .instrument-name');
+ fileItemsMMP.forEach(function (item) {
+ var instrumentsList = item.querySelectorAll(
+ ".instrument-list .instrument-name"
+ );
var hasInstrument = false;
- instrumentsList.forEach(function(instrument) {
- var instrumentName = instrument.getAttribute('data-instrument').toLowerCase();
+ instrumentsList.forEach(function (instrument) {
+ var instrumentName = instrument
+ .getAttribute("data-instrument")
+ .toLowerCase();
if (instrumentName.includes(searchInput)) {
hasInstrument = true;
}
});
if (hasInstrument) {
- item.style.display = 'block';
+ item.style.display = "block";
} else {
- item.style.display = 'none';
+ item.style.display = "none";
}
});
// Exibir a lista de arquivos MMP após a busca
- document.getElementById('file-list-mmp').style.display = 'block';
+ document.getElementById("file-list-mmp").style.display = "block";
});
// Buscar por nome de arquivo WAV usando o campo de entrada
- var searchWavButton = document.getElementById('search-wav-button');
- searchWavButton.addEventListener('click', function() {
- var searchInput = document.getElementById('file-wav-search').value.trim().toLowerCase();
- if (searchInput === '') {
+ var searchWavButton = document.getElementById("search-wav-button");
+ searchWavButton.addEventListener("click", function () {
+ var searchInput = document
+ .getElementById("file-wav-search")
+ .value.trim()
+ .toLowerCase();
+ if (searchInput === "") {
resetSearch();
return;
}
- fileItemsWAV.forEach(function(item) {
- var fileName = item.querySelector('span').textContent.toLowerCase();
+ fileItemsWAV.forEach(function (item) {
+ var fileName = item.querySelector("span").textContent.toLowerCase();
if (fileName.includes(searchInput)) {
- item.style.display = 'block';
+ item.style.display = "block";
} else {
- item.style.display = 'none';
+ item.style.display = "none";
}
});
// Exibir a lista de arquivos WAV após a busca
- document.getElementById('file-list-wav').style.display = 'block';
+ document.getElementById("file-list-wav").style.display = "block";
});
// Buscar por instrumento ou nome de arquivo WAV usando o campo de entrada combinado
- var searchBothButton = document.getElementById('search-both-button');
- searchBothButton.addEventListener('click', function() {
- var searchInput = document.getElementById('instrument-wav-search').value.trim().toLowerCase();
- if (searchInput === '') {
+ var searchBothButton = document.getElementById("search-both-button");
+ searchBothButton.addEventListener("click", function () {
+ var searchInput = document
+ .getElementById("instrument-wav-search")
+ .value.trim()
+ .toLowerCase();
+ if (searchInput === "") {
resetSearch();
return;
}
// Buscar em arquivos MMP por instrumento
- fileItemsMMP.forEach(function(item) {
- var instrumentsList = item.querySelectorAll('.instrument-list .instrument-name');
+ fileItemsMMP.forEach(function (item) {
+ var instrumentsList = item.querySelectorAll(
+ ".instrument-list .instrument-name"
+ );
var hasInstrument = false;
- instrumentsList.forEach(function(instrument) {
- var instrumentName = instrument.getAttribute('data-instrument').toLowerCase();
+ instrumentsList.forEach(function (instrument) {
+ var instrumentName = instrument
+ .getAttribute("data-instrument")
+ .toLowerCase();
if (instrumentName.includes(searchInput)) {
hasInstrument = true;
// Mostrar arquivo WAV correspondente ao instrumento
- showWAVFilesByInstrument(item.getAttribute('data-file'));
+ showWAVFilesByInstrument(item.getAttribute("data-file"));
}
});
if (hasInstrument) {
- item.style.display = 'block';
+ item.style.display = "block";
} else {
- item.style.display = 'none';
+ item.style.display = "none";
}
});
// Exibir as listas de arquivos após a busca
- document.getElementById('file-list-mmp').style.display = 'block';
- document.getElementById('file-list-wav').style.display = 'block';
+ document.getElementById("file-list-mmp").style.display = "block";
+ document.getElementById("file-list-wav").style.display = "block";
});
// Função para resetar a busca
function resetSearch() {
- fileItemsMMP.forEach(function(item) {
- item.style.display = 'block';
+ fileItemsMMP.forEach(function (item) {
+ item.style.display = "block";
});
- fileItemsWAV.forEach(function(item) {
- item.style.display = 'block';
+ fileItemsWAV.forEach(function (item) {
+ item.style.display = "block";
});
- document.getElementById('file-list-mmp').style.display = 'none';
- document.getElementById('file-list-wav').style.display = 'none';
+ document.getElementById("file-list-mmp").style.display = "none";
+ document.getElementById("file-list-wav").style.display = "none";
}
-
});
-
diff --git a/automation.html b/automation.html
index cb0c9a5..d69abea 100644
--- a/automation.html
+++ b/automation.html
@@ -3,18 +3,19 @@ layout: default
title: Projetos com a tag Automation
permalink: /automation/
---
-
-
-
- {% include sidebar.html %}
-
+
+
+
+ {% include sidebar.html %}
-
+
-
Projetos que possuem a tag automation:
+
+ Projetos que possuem a tag automation:
+
@@ -26,99 +27,104 @@ permalink: /automation/
- {% for projeto in site.data.all %}
- {% if projeto.tags.TAG contains "automation" %}
-
-
-
- {% assign file_url = projeto.file | downcase
- | replace: ' ', '-'
- | replace: 'ç', 'c'
- | replace: 'ã', 'a'
- | replace: 'á', 'a'
- | replace: 'â', 'a'
- | replace: 'é', 'e'
- | replace: 'ê', 'e'
- | replace: 'í', 'i'
- | replace: 'ó', 'o'
- | replace: 'ô', 'o'
- | replace: 'õ', 'o'
- | replace: 'ú', 'u' %}
+ {% for projeto in site.data.all %} {% if projeto.tags.TAG contains
+ "automation" %}
+
+
+
+ {% assign file_url = projeto.file | downcase | replace: ' ', '-' |
+ replace: 'ç', 'c' | replace: 'ã', 'a' | replace: 'á', 'a' | replace:
+ 'â', 'a' | replace: 'é', 'e' | replace: 'ê', 'e' | replace: 'í', 'i' |
+ replace: 'ó', 'o' | replace: 'ô', 'o' | replace: 'õ', 'o' | replace:
+ 'ú', 'u' %}
-
- {{ projeto.file }}
-
+
+ {{ projeto.file }}
+
-
- {% if projeto.tags.automation and projeto.tags.automation.size > 0 %}
-
-
Automation:
-
- {% for automation in projeto.tags.automation %}
- {% if automation != "" %}
- {{ automation }}
- {% endif %}
- {% endfor %}
-
-
- {% endif %}
-
+
+ {% if projeto.tags.automation and projeto.tags.automation.size > 0 %}
+
+
Automation:
+
+ {% for automation in projeto.tags.automation %} {% if automation
+ != "" %}
+
+ {{ automation }}
+
+ {% endif %} {% endfor %}
+
- {% endif %}
- {% endfor %}
+ {% endif %}
+
+
+ {% endif %} {% endfor %}
\ No newline at end of file
+
diff --git a/bassline.html b/bassline.html
index 9e08279..00e482c 100644
--- a/bassline.html
+++ b/bassline.html
@@ -3,18 +3,19 @@ layout: default
title: Projetos com a tag Bassline
permalink: /bassline/
---
-
-
-
- {% include sidebar.html %}
-
+
+
+
+ {% include sidebar.html %}
-
+
-
Projetos que possuem a tag bassline:
+
+ Projetos que possuem a tag bassline:
+
@@ -26,109 +27,111 @@ permalink: /bassline/
- {% for projeto in site.data.all %}
- {% if projeto.tags.TAG contains "bassline" %}
-
-
-
- {% assign file_url = projeto.file | downcase
- | replace: ' ', '-'
- | replace: 'ç', 'c'
- | replace: 'ã', 'a'
- | replace: 'á', 'a'
- | replace: 'â', 'a'
- | replace: 'é', 'e'
- | replace: 'ê', 'e'
- | replace: 'í', 'i'
- | replace: 'ó', 'o'
- | replace: 'ô', 'o'
- | replace: 'õ', 'o'
- | replace: 'ú', 'u' %}
+ {% for projeto in site.data.all %} {% if projeto.tags.TAG contains
+ "bassline" %}
+
+
+
+ {% assign file_url = projeto.file | downcase | replace: ' ', '-' |
+ replace: 'ç', 'c' | replace: 'ã', 'a' | replace: 'á', 'a' | replace:
+ 'â', 'a' | replace: 'é', 'e' | replace: 'ê', 'e' | replace: 'í', 'i' |
+ replace: 'ó', 'o' | replace: 'ô', 'o' | replace: 'õ', 'o' | replace:
+ 'ú', 'u' %}
-
- {{ projeto.file }}
-
+
+ {{ projeto.file }}
+
-
- {% if projeto.tags.bassline and projeto.tags.bassline.size > 0 %}
-
-
Bassline:
-
- {% for bassline in projeto.tags.bassline %}
- {% if bassline != "" %}
- {{ bassline }}
- {% endif %}
- {% endfor %}
-
-
- {% endif %}
-
+
+ {% if projeto.tags.bassline and projeto.tags.bassline.size > 0 %}
+
+
Bassline:
+
+ {% for bassline in projeto.tags.bassline %} {% if bassline != ""
+ %}
+
+ {{ bassline }}
+
+ {% endif %} {% endfor %}
+
- {% endif %}
- {% endfor %}
+ {% endif %}
+
+
+ {% endif %} {% endfor %}
+
+
+
+