MMPCreator
This commit is contained in:
1 parent
0dda2b1b0c
commit
8395783986
22 files changed
+2883
-460
No files matched your search
@@ -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"
|
|
||||||
]
|
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
<a href="{{ site.baseurl }}projetosPorTrack/">📁 Projetos por tipo de track</a>
|
<a href="{{ site.baseurl }}projetosPorTrack/">📁 Projetos por tipo de track</a>
|
||||||
<a href="{{ site.baseurl }}beatsDisponiveis/">🎧 Beats Disponíveis</a>
|
<a href="{{ site.baseurl }}beatsDisponiveis/">🎧 Beats Disponíveis</a>
|
||||||
<a href="{{ site.baseurl }}mmp_pages/">🎼 Projetos</a>
|
<a href="{{ site.baseurl }}mmp_pages/">🎼 Projetos</a>
|
||||||
<a href="{{ site.baseurl }}">🔎 Buscas</a>
|
<a href="{{ site.baseurl }}">🔎 Buscas</a>´
|
||||||
|
<a href="creation.html">🧠 Crie seu projeto</a>
|
||||||
<a href="{{ site.baseurl }}about/">ℹ️ Sobre</a>
|
<a href="{{ site.baseurl }}about/">ℹ️ Sobre</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<a href="{{ site.baseurl }}beatsDisponiveis/" style="text-decoration: none; color: #333;">🎧 Beats Disponíveis</a>
|
<a href="{{ site.baseurl }}beatsDisponiveis/" style="text-decoration: none; color: #333;">🎧 Beats Disponíveis</a>
|
||||||
<a href="{{ site.baseurl }}mmp_pages/" style="text-decoration: none; color: #333;">🎼 Projetos Disponíveis</a>
|
<a href="{{ site.baseurl }}mmp_pages/" style="text-decoration: none; color: #333;">🎼 Projetos Disponíveis</a>
|
||||||
<a href="{{ site.baseurl }}" style="text-decoration: none; color: #333;">🔎 Buscas</a>
|
<a href="{{ site.baseurl }}" style="text-decoration: none; color: #333;">🔎 Buscas</a>
|
||||||
|
<a href="creation.html" style="text-decoration: none; color: #333;">🧠 Crie seu projeto</a>
|
||||||
<a href="{{ site.baseurl }}about/" style="text-decoration: none; color: #333;">ℹ️ Sobre</a>
|
<a href="{{ site.baseurl }}about/" style="text-decoration: none; color: #333;">ℹ️ Sobre</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ title: "{{ page.file }}"
|
|||||||
<div class="audio-player-section mt-3">
|
<div class="audio-player-section mt-3">
|
||||||
<audio controls>
|
<audio controls>
|
||||||
<!-- O caminho, aparentemente, está correto. mas não está emitindo sons -->
|
<!-- O caminho, aparentemente, está correto. mas não está emitindo sons -->
|
||||||
<source src="{{ '/mmp/instruments/lmms/' | append: audiofileprocessor.src | relative_url }}" type="audio/wav">
|
<source src="{{ '/mmp/instruments/lmms/' | append: instrument.audiofileprocessor.src | relative_url }}" type="audio/wav">
|
||||||
<source src="{{ '/mmp/instruments/lmms/' | append: audiofileprocessor.src | relative_url }}" type="audio/ogg">
|
<source src="{{ '/mmp/instruments/lmms/' | append: instrument.audiofileprocessor.src | relative_url }}" type="audio/ogg">
|
||||||
Seu navegador não suporta o elemento <code>audio</code>.
|
Seu navegador não suporta o elemento <code>audio</code>.
|
||||||
</audio>
|
</audio>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
background-color: #f4f4f4;
|
background-color: #f4f4f4;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 8px;
|
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%;
|
max-width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@@ -40,4 +40,3 @@
|
|||||||
padding: 0.3rem 0.6rem;
|
padding: 0.3rem 0.6rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+31
-32
@@ -1,33 +1,32 @@
|
|||||||
.sidebar-center {
|
.sidebar-center {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
background-color: #f4f4f4;
|
background-color: #f4f4f4;
|
||||||
padding: 2rem 1.5rem;
|
padding: 2rem 1.5rem;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu {
|
.submenu {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu a {
|
.submenu a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu a:hover {
|
.submenu a:hover {
|
||||||
background-color: #e0e0e0;
|
background-color: #e0e0e0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
@@ -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 = `<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE lmms-project>
|
||||||
|
<lmms-project version="1.0" type="song" creator="MMPCreator" creatorversion="1.0">
|
||||||
|
<head mastervol="100" timesig_denominator="${sig_den}" bpm="${bpm}" timesig_numerator="${sig_num}" masterpitch="0"/>
|
||||||
|
<song>
|
||||||
|
<trackcontainer type="song">
|
||||||
|
<track type="1" solo="0" muted="0" name="Beat/Bassline 0">
|
||||||
|
<bbtrack>
|
||||||
|
<trackcontainer type="bbtrackcontainer">
|
||||||
|
${tracksXml}
|
||||||
|
</trackcontainer>
|
||||||
|
</bbtrack>
|
||||||
|
<bbtco color="4286611584" len="192" usestyle="1" pos="0" muted="0" name="Pattern 1"/>
|
||||||
|
</track>
|
||||||
|
</trackcontainer>
|
||||||
|
<timeline lp1pos="192" lp0pos="0" lpstate="0"/>
|
||||||
|
<controllers/>
|
||||||
|
<projectnotes width="686" y="10" minimized="0" visible="0" x="700" maximized="0" height="400"><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body>
|
||||||
|
<p>Feito com MMPCreator no https://alice.ufsj.edu.br/MMPSearch/creator</p>
|
||||||
|
</body></html>]]></projectnotes>
|
||||||
|
</song>
|
||||||
|
</lmms-project>`;
|
||||||
|
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(
|
||||||
|
`<root>${tracksXml}</root>`,
|
||||||
|
"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 `<note vol="100" len="${NOTE_LENGTH}" pos="${notePos}" pan="0" key="57"/>`;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
})
|
||||||
|
.join("\n ");
|
||||||
|
return `
|
||||||
|
<track type="0" solo="0" muted="0" name="${track.name}">
|
||||||
|
<instrumenttrack vol="${lmmsVolume}" pitch="0" fxch="0" pitchrange="1" basenote="57" usemasterpitch="1" pan="${lmmsPan}">
|
||||||
|
<instrument name="audiofileprocessor">
|
||||||
|
<audiofileprocessor eframe="1" stutter="0" looped="0" interp="1" reversed="0" lframe="0" src="${sampleSrc}" amp="100" sframe="0"/>
|
||||||
|
</instrument>
|
||||||
|
<fxchain enabled="0" numofeffects="0"/>
|
||||||
|
</instrumenttrack>
|
||||||
|
<pattern type="0" pos="0" muted="0" steps="${totalSteps}" name="${track.name}">
|
||||||
|
${notesXml}
|
||||||
|
</pattern>
|
||||||
|
</track>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
});
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 = `
|
||||||
|
<div class="track-info"><i class="fa-solid fa-gear"></i><div class="track-mute"></div><span class="track-name">${trackData.name}</span></div>
|
||||||
|
<div class="track-controls">
|
||||||
|
<div class="knob-container">
|
||||||
|
<div class="knob" data-control="volume" data-track-id="${trackData.id}">
|
||||||
|
<div class="knob-indicator"></div>
|
||||||
|
</div>
|
||||||
|
<span>VOL</span>
|
||||||
|
</div>
|
||||||
|
<div class="knob-container">
|
||||||
|
<div class="knob" data-control="pan" data-track-id="${trackData.id}">
|
||||||
|
<div class="knob-indicator"></div>
|
||||||
|
</div>
|
||||||
|
<span>PAN</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step-sequencer"></div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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 = `<p style="color:var(--accent-red); padding: 10px;">${error.message}</p>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = `<i class="fa-solid fa-file-audio"></i> ${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 = `<i class="fa-solid fa-folder"></i> ${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 = "<p>Carregando...</p>";
|
||||||
|
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 =
|
||||||
|
'<p style="color:var(--text-dark);">Nenhum projeto encontrado no servidor.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = `<p style="color:var(--accent-red);">${error.message}</p>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeOpenProjectModal() {
|
||||||
|
const openProjectModal = document.getElementById("open-project-modal");
|
||||||
|
openProjectModal.classList.remove("visible");
|
||||||
|
}
|
||||||
@@ -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 }));
|
||||||
|
}
|
||||||
+63
-48
@@ -1,108 +1,123 @@
|
|||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
var fileItemsMMP = document.querySelectorAll('#file-list-mmp .file-item');
|
var fileItemsMMP = document.querySelectorAll("#file-list-mmp .file-item");
|
||||||
var fileItemsWAV = document.querySelectorAll('#file-list-wav .file-wav-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
|
// Função para exibir apenas os arquivos WAV correspondentes aos instrumentos encontrados nos projetos MMP
|
||||||
function showWAVFilesByInstrument(selectedInstrument) {
|
function showWAVFilesByInstrument(selectedInstrument) {
|
||||||
fileItemsWAV.forEach(function(item) {
|
fileItemsWAV.forEach(function (item) {
|
||||||
var fileName = item.getAttribute('data-file').toLowerCase();
|
var fileName = item.getAttribute("data-file").toLowerCase();
|
||||||
if (fileName.includes(selectedInstrument)) {
|
if (fileName.includes(selectedInstrument)) {
|
||||||
item.style.display = 'block';
|
item.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
item.style.display = 'none';
|
item.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buscar por instrumento usando o campo de entrada para MMP
|
// Buscar por instrumento usando o campo de entrada para MMP
|
||||||
var searchButton = document.getElementById('search-button');
|
var searchButton = document.getElementById("search-button");
|
||||||
searchButton.addEventListener('click', function() {
|
searchButton.addEventListener("click", function () {
|
||||||
var searchInput = document.getElementById('instrument-search').value.trim().toLowerCase();
|
var searchInput = document
|
||||||
if (searchInput === '') {
|
.getElementById("instrument-search")
|
||||||
|
.value.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
if (searchInput === "") {
|
||||||
resetSearch();
|
resetSearch();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileItemsMMP.forEach(function(item) {
|
fileItemsMMP.forEach(function (item) {
|
||||||
var instrumentsList = item.querySelectorAll('.instrument-list .instrument-name');
|
var instrumentsList = item.querySelectorAll(
|
||||||
|
".instrument-list .instrument-name"
|
||||||
|
);
|
||||||
var hasInstrument = false;
|
var hasInstrument = false;
|
||||||
instrumentsList.forEach(function(instrument) {
|
instrumentsList.forEach(function (instrument) {
|
||||||
var instrumentName = instrument.getAttribute('data-instrument').toLowerCase();
|
var instrumentName = instrument
|
||||||
|
.getAttribute("data-instrument")
|
||||||
|
.toLowerCase();
|
||||||
if (instrumentName.includes(searchInput)) {
|
if (instrumentName.includes(searchInput)) {
|
||||||
hasInstrument = true;
|
hasInstrument = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (hasInstrument) {
|
if (hasInstrument) {
|
||||||
item.style.display = 'block';
|
item.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
item.style.display = 'none';
|
item.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Exibir a lista de arquivos MMP após a busca
|
// 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
|
// Buscar por nome de arquivo WAV usando o campo de entrada
|
||||||
var searchWavButton = document.getElementById('search-wav-button');
|
var searchWavButton = document.getElementById("search-wav-button");
|
||||||
searchWavButton.addEventListener('click', function() {
|
searchWavButton.addEventListener("click", function () {
|
||||||
var searchInput = document.getElementById('file-wav-search').value.trim().toLowerCase();
|
var searchInput = document
|
||||||
if (searchInput === '') {
|
.getElementById("file-wav-search")
|
||||||
|
.value.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
if (searchInput === "") {
|
||||||
resetSearch();
|
resetSearch();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileItemsWAV.forEach(function(item) {
|
fileItemsWAV.forEach(function (item) {
|
||||||
var fileName = item.querySelector('span').textContent.toLowerCase();
|
var fileName = item.querySelector("span").textContent.toLowerCase();
|
||||||
if (fileName.includes(searchInput)) {
|
if (fileName.includes(searchInput)) {
|
||||||
item.style.display = 'block';
|
item.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
item.style.display = 'none';
|
item.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Exibir a lista de arquivos WAV após a busca
|
// 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
|
// Buscar por instrumento ou nome de arquivo WAV usando o campo de entrada combinado
|
||||||
var searchBothButton = document.getElementById('search-both-button');
|
var searchBothButton = document.getElementById("search-both-button");
|
||||||
searchBothButton.addEventListener('click', function() {
|
searchBothButton.addEventListener("click", function () {
|
||||||
var searchInput = document.getElementById('instrument-wav-search').value.trim().toLowerCase();
|
var searchInput = document
|
||||||
if (searchInput === '') {
|
.getElementById("instrument-wav-search")
|
||||||
|
.value.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
if (searchInput === "") {
|
||||||
resetSearch();
|
resetSearch();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Buscar em arquivos MMP por instrumento
|
// Buscar em arquivos MMP por instrumento
|
||||||
fileItemsMMP.forEach(function(item) {
|
fileItemsMMP.forEach(function (item) {
|
||||||
var instrumentsList = item.querySelectorAll('.instrument-list .instrument-name');
|
var instrumentsList = item.querySelectorAll(
|
||||||
|
".instrument-list .instrument-name"
|
||||||
|
);
|
||||||
var hasInstrument = false;
|
var hasInstrument = false;
|
||||||
instrumentsList.forEach(function(instrument) {
|
instrumentsList.forEach(function (instrument) {
|
||||||
var instrumentName = instrument.getAttribute('data-instrument').toLowerCase();
|
var instrumentName = instrument
|
||||||
|
.getAttribute("data-instrument")
|
||||||
|
.toLowerCase();
|
||||||
if (instrumentName.includes(searchInput)) {
|
if (instrumentName.includes(searchInput)) {
|
||||||
hasInstrument = true;
|
hasInstrument = true;
|
||||||
// Mostrar arquivo WAV correspondente ao instrumento
|
// Mostrar arquivo WAV correspondente ao instrumento
|
||||||
showWAVFilesByInstrument(item.getAttribute('data-file'));
|
showWAVFilesByInstrument(item.getAttribute("data-file"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (hasInstrument) {
|
if (hasInstrument) {
|
||||||
item.style.display = 'block';
|
item.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
item.style.display = 'none';
|
item.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Exibir as listas de arquivos após a busca
|
// Exibir as listas de arquivos após a busca
|
||||||
document.getElementById('file-list-mmp').style.display = 'block';
|
document.getElementById("file-list-mmp").style.display = "block";
|
||||||
document.getElementById('file-list-wav').style.display = 'block';
|
document.getElementById("file-list-wav").style.display = "block";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Função para resetar a busca
|
// Função para resetar a busca
|
||||||
function resetSearch() {
|
function resetSearch() {
|
||||||
fileItemsMMP.forEach(function(item) {
|
fileItemsMMP.forEach(function (item) {
|
||||||
item.style.display = 'block';
|
item.style.display = "block";
|
||||||
});
|
});
|
||||||
fileItemsWAV.forEach(function(item) {
|
fileItemsWAV.forEach(function (item) {
|
||||||
item.style.display = 'block';
|
item.style.display = "block";
|
||||||
});
|
});
|
||||||
document.getElementById('file-list-mmp').style.display = 'none';
|
document.getElementById("file-list-mmp").style.display = "none";
|
||||||
document.getElementById('file-list-wav').style.display = 'none';
|
document.getElementById("file-list-wav").style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
+70
-64
@@ -3,18 +3,19 @@ layout: default
|
|||||||
title: Projetos com a tag Automation
|
title: Projetos com a tag Automation
|
||||||
permalink: /automation/
|
permalink: /automation/
|
||||||
---
|
---
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<main class="main-content">
|
<meta charset="utf-8" />
|
||||||
<div class="publication">
|
|
||||||
{% include sidebar.html %}
|
<main class="main-content">
|
||||||
</div>
|
<div class="publication">{% include sidebar.html %}</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="columns is-mobile is-vcentered" style="margin-bottom: 2rem;">
|
<div class="columns is-mobile is-vcentered" style="margin-bottom: 2rem">
|
||||||
<!-- Título -->
|
<!-- Título -->
|
||||||
<div class="column is-auto">
|
<div class="column is-auto">
|
||||||
<h2 class="title is-4"><code>Projetos que possuem a tag automation:</code></h2>
|
<h2 class="title is-4">
|
||||||
|
<code>Projetos que possuem a tag automation:</code>
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<!-- Botão Limpar Filtro -->
|
<!-- Botão Limpar Filtro -->
|
||||||
<div class="column is-auto">
|
<div class="column is-auto">
|
||||||
@@ -26,99 +27,104 @@ permalink: /automation/
|
|||||||
|
|
||||||
<!-- Projetos -->
|
<!-- Projetos -->
|
||||||
<div id="project-list" class="columns is-multiline">
|
<div id="project-list" class="columns is-multiline">
|
||||||
{% for projeto in site.data.all %}
|
{% for projeto in site.data.all %} {% if projeto.tags.TAG contains
|
||||||
{% if projeto.tags.TAG contains "automation" %}
|
"automation" %}
|
||||||
<div class="column is-6 project-item" data-automation="{{ projeto.tags.automation | join: ',' }}">
|
<div
|
||||||
<div class="box">
|
class="column is-6 project-item"
|
||||||
<!-- Botão do projeto -->
|
data-automation="{{ projeto.tags.automation | join: ',' }}"
|
||||||
{% assign file_url = projeto.file | downcase
|
>
|
||||||
| replace: ' ', '-'
|
<div class="box">
|
||||||
| replace: 'ç', 'c'
|
<!-- Botão do projeto -->
|
||||||
| replace: 'ã', 'a'
|
{% assign file_url = projeto.file | downcase | replace: ' ', '-' |
|
||||||
| replace: 'á', 'a'
|
replace: 'ç', 'c' | replace: 'ã', 'a' | replace: 'á', 'a' | replace:
|
||||||
| replace: 'â', 'a'
|
'â', 'a' | replace: 'é', 'e' | replace: 'ê', 'e' | replace: 'í', 'i' |
|
||||||
| replace: 'é', 'e'
|
replace: 'ó', 'o' | replace: 'ô', 'o' | replace: 'õ', 'o' | replace:
|
||||||
| replace: 'ê', 'e'
|
'ú', 'u' %}
|
||||||
| replace: 'í', 'i'
|
|
||||||
| replace: 'ó', 'o'
|
|
||||||
| replace: 'ô', 'o'
|
|
||||||
| replace: 'õ', 'o'
|
|
||||||
| replace: 'ú', 'u' %}
|
|
||||||
|
|
||||||
<a href="../mmp_pages/{{ file_url }}.html" class="button is-link is-fullwidth">
|
<a
|
||||||
{{ projeto.file }}
|
href="../mmp_pages/{{ file_url }}.html"
|
||||||
</a>
|
class="button is-link is-fullwidth"
|
||||||
|
>
|
||||||
|
{{ projeto.file }}
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- Lista de automations clicáveis -->
|
<!-- Lista de automations clicáveis -->
|
||||||
{% if projeto.tags.automation and projeto.tags.automation.size > 0 %}
|
{% if projeto.tags.automation and projeto.tags.automation.size > 0 %}
|
||||||
<div style="margin-top: 1rem;">
|
<div style="margin-top: 1rem">
|
||||||
<p><strong>Automation:</strong></p>
|
<p><strong>Automation:</strong></p>
|
||||||
<ul style="list-style-type: disc; padding-left: 1.25rem;">
|
<ul style="list-style-type: disc; padding-left: 1.25rem">
|
||||||
{% for automation in projeto.tags.automation %}
|
{% for automation in projeto.tags.automation %} {% if automation
|
||||||
{% if automation != "" %}
|
!= "" %}
|
||||||
<li><a href="#" class="automation-item" data-automation="{{ automation }}">{{ automation }}</a></li>
|
<li>
|
||||||
{% endif %}
|
<a
|
||||||
{% endfor %}
|
href="#"
|
||||||
</ul>
|
class="automation-item"
|
||||||
</div>
|
data-automation="{{ automation }}"
|
||||||
{% endif %}
|
>{{ automation }}</a
|
||||||
</div>
|
>
|
||||||
|
</li>
|
||||||
|
{% endif %} {% endfor %}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %} {% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
const projects = document.querySelectorAll('.project-item');
|
const projects = document.querySelectorAll(".project-item");
|
||||||
|
|
||||||
// Função para aplicar filtro por automation
|
// Função para aplicar filtro por automation
|
||||||
function filterByAutomation(automationName) {
|
function filterByAutomation(automationName) {
|
||||||
projects.forEach(project => {
|
projects.forEach((project) => {
|
||||||
const projectAutomations = project.getAttribute('data-automation').split(',');
|
const projectAutomations = project
|
||||||
|
.getAttribute("data-automation")
|
||||||
|
.split(",");
|
||||||
if (projectAutomations.includes(automationName)) {
|
if (projectAutomations.includes(automationName)) {
|
||||||
project.style.display = 'block';
|
project.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
project.style.display = 'none';
|
project.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lê a automation da URL se houver
|
// Lê a automation da URL se houver
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const automationFromUrl = urlParams.get('automation');
|
const automationFromUrl = urlParams.get("automation");
|
||||||
if (automationFromUrl) {
|
if (automationFromUrl) {
|
||||||
filterByAutomation(automationFromUrl);
|
filterByAutomation(automationFromUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ao clicar numa automation na lista
|
// Ao clicar numa automation na lista
|
||||||
const automationItems = document.querySelectorAll('.automation-item');
|
const automationItems = document.querySelectorAll(".automation-item");
|
||||||
automationItems.forEach(item => {
|
automationItems.forEach((item) => {
|
||||||
item.addEventListener('click', function (event) {
|
item.addEventListener("click", function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const selectedAutomation = item.getAttribute('data-automation');
|
const selectedAutomation = item.getAttribute("data-automation");
|
||||||
filterByAutomation(selectedAutomation);
|
filterByAutomation(selectedAutomation);
|
||||||
|
|
||||||
// Atualiza a URL sem recarregar a página
|
// Atualiza a URL sem recarregar a página
|
||||||
const newUrl = new URL(window.location.href);
|
const newUrl = new URL(window.location.href);
|
||||||
newUrl.searchParams.set('automation', selectedAutomation);
|
newUrl.searchParams.set("automation", selectedAutomation);
|
||||||
window.history.replaceState({}, '', newUrl);
|
window.history.replaceState({}, "", newUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Botão para limpar filtro
|
// Botão para limpar filtro
|
||||||
const clearFilterButton = document.querySelector('#clearFilterButton');
|
const clearFilterButton = document.querySelector("#clearFilterButton");
|
||||||
clearFilterButton.addEventListener('click', function () {
|
clearFilterButton.addEventListener("click", function () {
|
||||||
projects.forEach(project => {
|
projects.forEach((project) => {
|
||||||
project.style.display = 'block';
|
project.style.display = "block";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove o filtro da URL
|
// Remove o filtro da URL
|
||||||
const newUrl = new URL(window.location.href);
|
const newUrl = new URL(window.location.href);
|
||||||
newUrl.searchParams.delete('automation');
|
newUrl.searchParams.delete("automation");
|
||||||
window.history.replaceState({}, '', newUrl);
|
window.history.replaceState({}, "", newUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
+71
-68
@@ -3,18 +3,19 @@ layout: default
|
|||||||
title: Projetos com a tag Bassline
|
title: Projetos com a tag Bassline
|
||||||
permalink: /bassline/
|
permalink: /bassline/
|
||||||
---
|
---
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<main class="main-content">
|
<meta charset="utf-8" />
|
||||||
<div class="publication">
|
|
||||||
{% include sidebar.html %}
|
<main class="main-content">
|
||||||
</div>
|
<div class="publication">{% include sidebar.html %}</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="columns is-mobile is-vcentered" style="margin-bottom: 2rem;">
|
<div class="columns is-mobile is-vcentered" style="margin-bottom: 2rem">
|
||||||
<!-- Título -->
|
<!-- Título -->
|
||||||
<div class="column is-auto">
|
<div class="column is-auto">
|
||||||
<h2 class="title is-4"><code>Projetos que possuem a tag bassline:</code></h2>
|
<h2 class="title is-4">
|
||||||
|
<code>Projetos que possuem a tag bassline:</code>
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<!-- Botão Limpar Filtro -->
|
<!-- Botão Limpar Filtro -->
|
||||||
<div class="column is-auto">
|
<div class="column is-auto">
|
||||||
@@ -26,109 +27,111 @@ permalink: /bassline/
|
|||||||
|
|
||||||
<!-- Projetos -->
|
<!-- Projetos -->
|
||||||
<div id="project-list" class="columns is-multiline">
|
<div id="project-list" class="columns is-multiline">
|
||||||
{% for projeto in site.data.all %}
|
{% for projeto in site.data.all %} {% if projeto.tags.TAG contains
|
||||||
{% if projeto.tags.TAG contains "bassline" %}
|
"bassline" %}
|
||||||
<div class="column is-6 project-item" data-bassline="{{ projeto.tags.bassline | join: ',' }}">
|
<div
|
||||||
<div class="box">
|
class="column is-6 project-item"
|
||||||
<!-- Botão do projeto -->
|
data-bassline="{{ projeto.tags.bassline | join: ',' }}"
|
||||||
{% assign file_url = projeto.file | downcase
|
>
|
||||||
| replace: ' ', '-'
|
<div class="box">
|
||||||
| replace: 'ç', 'c'
|
<!-- Botão do projeto -->
|
||||||
| replace: 'ã', 'a'
|
{% assign file_url = projeto.file | downcase | replace: ' ', '-' |
|
||||||
| replace: 'á', 'a'
|
replace: 'ç', 'c' | replace: 'ã', 'a' | replace: 'á', 'a' | replace:
|
||||||
| replace: 'â', 'a'
|
'â', 'a' | replace: 'é', 'e' | replace: 'ê', 'e' | replace: 'í', 'i' |
|
||||||
| replace: 'é', 'e'
|
replace: 'ó', 'o' | replace: 'ô', 'o' | replace: 'õ', 'o' | replace:
|
||||||
| replace: 'ê', 'e'
|
'ú', 'u' %}
|
||||||
| replace: 'í', 'i'
|
|
||||||
| replace: 'ó', 'o'
|
|
||||||
| replace: 'ô', 'o'
|
|
||||||
| replace: 'õ', 'o'
|
|
||||||
| replace: 'ú', 'u' %}
|
|
||||||
|
|
||||||
<a href="../mmp_pages/{{ file_url }}.html" class="button is-link is-fullwidth">
|
<a
|
||||||
{{ projeto.file }}
|
href="../mmp_pages/{{ file_url }}.html"
|
||||||
</a>
|
class="button is-link is-fullwidth"
|
||||||
|
>
|
||||||
|
{{ projeto.file }}
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- Lista de Basslines clicáveis -->
|
<!-- Lista de Basslines clicáveis -->
|
||||||
{% if projeto.tags.bassline and projeto.tags.bassline.size > 0 %}
|
{% if projeto.tags.bassline and projeto.tags.bassline.size > 0 %}
|
||||||
<div style="margin-top: 1rem;">
|
<div style="margin-top: 1rem">
|
||||||
<p><strong>Bassline:</strong></p>
|
<p><strong>Bassline:</strong></p>
|
||||||
<ul style="list-style-type: disc; padding-left: 1.25rem;">
|
<ul style="list-style-type: disc; padding-left: 1.25rem">
|
||||||
{% for bassline in projeto.tags.bassline %}
|
{% for bassline in projeto.tags.bassline %} {% if bassline != ""
|
||||||
{% if bassline != "" %}
|
%}
|
||||||
<li><a href="#" class="bassline-item" data-bassline="{{ bassline }}">{{ bassline }}</a></li>
|
<li>
|
||||||
{% endif %}
|
<a href="#" class="bassline-item" data-bassline="{{ bassline }}"
|
||||||
{% endfor %}
|
>{{ bassline }}</a
|
||||||
</ul>
|
>
|
||||||
</div>
|
</li>
|
||||||
{% endif %}
|
{% endif %} {% endfor %}
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %} {% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
const projects = document.querySelectorAll('.project-item');
|
const projects = document.querySelectorAll(".project-item");
|
||||||
|
|
||||||
// Função para aplicar filtro por bassline
|
// Função para aplicar filtro por bassline
|
||||||
function filterByBassline(basslineName) {
|
function filterByBassline(basslineName) {
|
||||||
projects.forEach(project => {
|
projects.forEach((project) => {
|
||||||
const projectBasslines = project.getAttribute('data-bassline').split(',');
|
const projectBasslines = project
|
||||||
|
.getAttribute("data-bassline")
|
||||||
|
.split(",");
|
||||||
if (projectBasslines.includes(basslineName)) {
|
if (projectBasslines.includes(basslineName)) {
|
||||||
project.style.display = 'block';
|
project.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
project.style.display = 'none';
|
project.style.display = "none";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lê o parâmetro bassline da URL (se houver)
|
// Lê o parâmetro bassline da URL (se houver)
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
let basslineFromUrl = urlParams.get('bassline');
|
let basslineFromUrl = urlParams.get("bassline");
|
||||||
|
|
||||||
// Substituir "+" por " " (espaços)
|
// Substituir "+" por " " (espaços)
|
||||||
if (basslineFromUrl) {
|
if (basslineFromUrl) {
|
||||||
basslineFromUrl = basslineFromUrl.replace(/\+/g, ' ');
|
basslineFromUrl = basslineFromUrl.replace(/\+/g, " ");
|
||||||
filterByBassline(basslineFromUrl);
|
filterByBassline(basslineFromUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ao clicar numa bassline na lista
|
// Ao clicar numa bassline na lista
|
||||||
const basslineItems = document.querySelectorAll('.bassline-item');
|
const basslineItems = document.querySelectorAll(".bassline-item");
|
||||||
if (basslineItems.length > 0) {
|
if (basslineItems.length > 0) {
|
||||||
basslineItems.forEach(item => {
|
basslineItems.forEach((item) => {
|
||||||
item.addEventListener('click', function (event) {
|
item.addEventListener("click", function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const selectedBassline = item.getAttribute('data-bassline');
|
const selectedBassline = item.getAttribute("data-bassline");
|
||||||
|
|
||||||
// Substitui espaços por "+"
|
// Substitui espaços por "+"
|
||||||
const basslineForUrl = selectedBassline.replace(/ /g, '+');
|
const basslineForUrl = selectedBassline.replace(/ /g, "+");
|
||||||
|
|
||||||
filterByBassline(selectedBassline);
|
filterByBassline(selectedBassline);
|
||||||
|
|
||||||
// Atualiza a URL sem recarregar a página
|
// Atualiza a URL sem recarregar a página
|
||||||
const newUrl = new URL(window.location.href);
|
const newUrl = new URL(window.location.href);
|
||||||
newUrl.searchParams.set('bassline', basslineForUrl);
|
newUrl.searchParams.set("bassline", basslineForUrl);
|
||||||
window.history.replaceState({}, '', newUrl);
|
window.history.replaceState({}, "", newUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Botão para limpar filtro
|
// Botão para limpar filtro
|
||||||
const clearFilterButton = document.querySelector('#clearFilterButton');
|
const clearFilterButton = document.querySelector("#clearFilterButton");
|
||||||
if (clearFilterButton) {
|
if (clearFilterButton) {
|
||||||
clearFilterButton.addEventListener('click', function () {
|
clearFilterButton.addEventListener("click", function () {
|
||||||
projects.forEach(project => {
|
projects.forEach((project) => {
|
||||||
project.style.display = 'block';
|
project.style.display = "block";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove o parâmetro bassline da URL
|
// Remove o parâmetro bassline da URL
|
||||||
const newUrl = new URL(window.location.href);
|
const newUrl = new URL(window.location.href);
|
||||||
newUrl.searchParams.delete('bassline');
|
newUrl.searchParams.delete("bassline");
|
||||||
window.history.replaceState({}, '', newUrl);
|
window.history.replaceState({}, "", newUrl);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+201
@@ -0,0 +1,201 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pt-br">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>MMPCreator</title>
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
|
||||||
|
/>
|
||||||
|
<link rel="stylesheet" href="assets/css/style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<aside class="sample-browser">
|
||||||
|
<div class="browser-header">Navegador de Samples</div>
|
||||||
|
<div class="browser-content" id="browser-content"></div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<button id="sidebar-toggle"><i class="fa-solid fa-caret-left"></i></button>
|
||||||
|
|
||||||
|
<header class="global-toolbar">
|
||||||
|
<div class="control-group">
|
||||||
|
<i
|
||||||
|
class="fa-solid fa-file"
|
||||||
|
id="new-project-btn"
|
||||||
|
title="Novo Projeto"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
class="fa-solid fa-folder-open"
|
||||||
|
id="open-mmp-btn"
|
||||||
|
title="Abrir Projeto (.mmp)"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
class="fa-solid fa-save"
|
||||||
|
id="save-mmp-btn"
|
||||||
|
title="Salvar Projeto (.mmp)"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<div class="control-group">
|
||||||
|
<i
|
||||||
|
class="fa-solid fa-backward-step"
|
||||||
|
id="rewind-btn"
|
||||||
|
title="Voltar ao Início"
|
||||||
|
></i>
|
||||||
|
<i class="fa-solid fa-play" title="Play/Pause Global (Futuro)"></i>
|
||||||
|
<i class="fa-solid fa-stop" title="Stop Global (Futuro)"></i>
|
||||||
|
<i class="fa-solid fa-circle-dot" title="Gravar"></i>
|
||||||
|
</div>
|
||||||
|
<div class="divider"></div>
|
||||||
|
<div class="info-display-group">
|
||||||
|
<div class="info-display">
|
||||||
|
<div class="interactive-input-container">
|
||||||
|
<button class="adjust-btn" data-target="bpm" data-step="-1">
|
||||||
|
-</button
|
||||||
|
><input
|
||||||
|
type="text"
|
||||||
|
class="value-input"
|
||||||
|
id="bpm-input"
|
||||||
|
value="140"
|
||||||
|
data-min="20"
|
||||||
|
data-max="400"
|
||||||
|
/><button class="adjust-btn" data-target="bpm" data-step="1">
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="label">ANDAMENTO/BPM</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-display">
|
||||||
|
<div class="interactive-input-container">
|
||||||
|
<div class="compasso-group">
|
||||||
|
<button
|
||||||
|
class="adjust-btn"
|
||||||
|
data-target="compasso-a"
|
||||||
|
data-step="-1"
|
||||||
|
>
|
||||||
|
-</button
|
||||||
|
><input
|
||||||
|
type="text"
|
||||||
|
class="value-input compasso-input"
|
||||||
|
id="compasso-a-input"
|
||||||
|
value="4"
|
||||||
|
data-min="1"
|
||||||
|
data-max="16"
|
||||||
|
/><button
|
||||||
|
class="adjust-btn"
|
||||||
|
data-target="compasso-a"
|
||||||
|
data-step="1"
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<span class="compasso-separator">/</span>
|
||||||
|
<div class="compasso-group">
|
||||||
|
<button
|
||||||
|
class="adjust-btn"
|
||||||
|
data-target="compasso-b"
|
||||||
|
data-step="-1"
|
||||||
|
>
|
||||||
|
-</button
|
||||||
|
><input
|
||||||
|
type="text"
|
||||||
|
class="value-input compasso-input"
|
||||||
|
id="compasso-b-input"
|
||||||
|
value="4"
|
||||||
|
data-min="1"
|
||||||
|
data-max="16"
|
||||||
|
/><button
|
||||||
|
class="adjust-btn"
|
||||||
|
data-target="compasso-b"
|
||||||
|
data-step="1"
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="label">COMPASSO</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-display">
|
||||||
|
<div
|
||||||
|
class="interactive-input-container"
|
||||||
|
style="font-size: 0.7rem; color: var(--text-dark)"
|
||||||
|
>
|
||||||
|
0:00:00
|
||||||
|
</div>
|
||||||
|
<div class="label">MIN:SEC:MSEC</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<button id="metronome-btn" title="Metrônomo On/Off">Metrônomo</button>
|
||||||
|
</div>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main-content">
|
||||||
|
<div class="beat-editor">
|
||||||
|
<div class="editor-header">
|
||||||
|
Mostrar/esconder Editor de Bases
|
||||||
|
<div class="window-controls">
|
||||||
|
<i class="fa-solid fa-minus"></i><i class="fa-regular fa-square"></i
|
||||||
|
><i class="fa-solid fa-xmark"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="editor-toolbar">
|
||||||
|
<div class="playback-controls">
|
||||||
|
<i class="fa-solid fa-play" id="play-btn" title="Play/Pause"></i>
|
||||||
|
<i class="fa-solid fa-stop" id="stop-btn" title="Stop"></i>
|
||||||
|
</div>
|
||||||
|
<div class="pattern-manager">
|
||||||
|
<select
|
||||||
|
id="pattern-selector"
|
||||||
|
class="pattern-selector-dropdown"
|
||||||
|
></select>
|
||||||
|
<button id="add-pattern-btn" class="pattern-btn">+</button>
|
||||||
|
<button id="remove-pattern-btn" class="pattern-btn">-</button>
|
||||||
|
</div>
|
||||||
|
<div class="tool-icons">
|
||||||
|
<i class="fa-solid fa-table-cells"></i
|
||||||
|
><i class="fa-solid fa-bars-staggered"></i
|
||||||
|
><i class="fa-solid fa-wave-square enabled"></i
|
||||||
|
><i class="fa-solid fa-plus"></i>
|
||||||
|
</div>
|
||||||
|
<div class="zoom-controls">
|
||||||
|
<i class="fa-solid fa-minus" id="remove-instrument-btn"></i
|
||||||
|
><i class="fa-solid fa-plus" id="add-instrument-btn"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="track-container"></div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="mmp-file-input"
|
||||||
|
accept=".mmp, .mmpz"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="modal-overlay" id="open-project-modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<button class="modal-close" id="open-modal-close-btn">×</button>
|
||||||
|
<h2 class="modal-title">Abrir Projeto</h2>
|
||||||
|
<div class="modal-section">
|
||||||
|
<h3>Projetos no Servidor</h3>
|
||||||
|
<div id="server-projects-list"><p>Carregando...</p></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-section">
|
||||||
|
<h3>Carregar do Computador</h3>
|
||||||
|
<button class="modal-button" id="load-from-computer-btn">
|
||||||
|
<i class="fa-solid fa-desktop"></i> Selecionar arquivo .mmp ou .mmpz
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
|
||||||
|
|
||||||
|
<script src="assets/js/creations/main.js" type="module" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
# --- Configuração de Caminhos Dinâmicos ---
|
||||||
|
# Descobre o caminho absoluto do script que está sendo executado.
|
||||||
|
# __file__ é uma variável especial do Python que contém o caminho para o arquivo atual.
|
||||||
|
SCRIPT_PATH = os.path.abspath(__file__)
|
||||||
|
|
||||||
|
# Descobre o diretório onde o script está (ex: /.../mmpSearch/scripts/creation)
|
||||||
|
SCRIPT_DIR = os.path.dirname(SCRIPT_PATH)
|
||||||
|
|
||||||
|
# Define a raiz do projeto subindo dois níveis de diretório (de 'creation' para 'scripts', e de 'scripts' para 'mmpSearch')
|
||||||
|
PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..'))
|
||||||
|
|
||||||
|
print(f"Raiz do projeto detectada em: {PROJECT_ROOT}")
|
||||||
|
|
||||||
|
|
||||||
|
# --- Configuração dos Manifestos ---
|
||||||
|
# Os caminhos aqui são relativos à RAIZ DO PROJETO.
|
||||||
|
CONFIGS = [
|
||||||
|
{
|
||||||
|
"source_dir": "src/samples",
|
||||||
|
"output_file": "metadata/samples-manifest.json",
|
||||||
|
"scan_type": "tree"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source_dir": "mmp",
|
||||||
|
"output_file": "metadata/mmp-manifest.json",
|
||||||
|
"scan_type": "list",
|
||||||
|
"extensions": ['.mmp', '.mmpz']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def scan_directory_tree(path):
|
||||||
|
"""
|
||||||
|
Função recursiva que escaneia um diretório e constrói uma
|
||||||
|
estrutura de dicionário (árvore) representando as pastas e arquivos.
|
||||||
|
"""
|
||||||
|
tree = {}
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
return tree
|
||||||
|
for item in os.listdir(path):
|
||||||
|
full_path = os.path.join(path, item)
|
||||||
|
if os.path.isdir(full_path):
|
||||||
|
tree[item] = scan_directory_tree(full_path)
|
||||||
|
else:
|
||||||
|
# (CORREÇÃO) Volte a usar o objeto que o JavaScript espera.
|
||||||
|
tree[item] = {"_isFile": True}
|
||||||
|
return tree
|
||||||
|
|
||||||
|
def scan_directory_list(path, allowed_extensions):
|
||||||
|
"""
|
||||||
|
Função que escaneia um diretório e retorna uma lista simples
|
||||||
|
de nomes de arquivos, filtrando por extensões permitidas.
|
||||||
|
"""
|
||||||
|
file_list = []
|
||||||
|
if not os.path.isdir(path): # Adiciona verificação
|
||||||
|
return file_list
|
||||||
|
for item in os.listdir(path):
|
||||||
|
full_path = os.path.join(path, item)
|
||||||
|
if os.path.isfile(full_path) and any(item.lower().endswith(ext) for ext in allowed_extensions):
|
||||||
|
file_list.append(item)
|
||||||
|
return sorted(file_list)
|
||||||
|
|
||||||
|
# --- Execução Principal do Script ---
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("\nIniciando geração de arquivos de manifesto...")
|
||||||
|
|
||||||
|
for config in CONFIGS:
|
||||||
|
# Monta os caminhos ABSOLUTOS usando a raiz do projeto
|
||||||
|
source_dir_abs = os.path.join(PROJECT_ROOT, config["source_dir"])
|
||||||
|
output_file_abs = os.path.join(PROJECT_ROOT, config["output_file"])
|
||||||
|
scan_type = config["scan_type"]
|
||||||
|
|
||||||
|
print(f"\nProcessando '{config['source_dir']}' -> '{config['output_file']}'...")
|
||||||
|
|
||||||
|
if not os.path.isdir(source_dir_abs):
|
||||||
|
print(f"AVISO: A pasta de origem '{source_dir_abs}' não foi encontrada. Arquivo não será gerado.")
|
||||||
|
continue
|
||||||
|
|
||||||
|
result_data = None
|
||||||
|
try:
|
||||||
|
if scan_type == "tree":
|
||||||
|
result_data = scan_directory_tree(source_dir_abs)
|
||||||
|
elif scan_type == "list":
|
||||||
|
extensions = config.get("extensions", [])
|
||||||
|
result_data = scan_directory_list(source_dir_abs, extensions)
|
||||||
|
|
||||||
|
if result_data is not None:
|
||||||
|
# Garante que o diretório de saída exista antes de salvar
|
||||||
|
output_dir = os.path.dirname(output_file_abs)
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
with open(output_file_abs, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(result_data, f, indent=2, ensure_ascii=False)
|
||||||
|
print(f"SUCESSO: Arquivo '{output_file_abs}' gerado!")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERRO inesperado ao processar a pasta '{source_dir_abs}': {e}")
|
||||||
|
|
||||||
|
print("\nGeração de manifestos concluída.")
|
||||||
@@ -25,7 +25,9 @@ def parse_automation(file_path):
|
|||||||
if automationtrack is not None:
|
if automationtrack is not None:
|
||||||
automation_info['automationtrack'] = 'Present'
|
automation_info['automationtrack'] = 'Present'
|
||||||
|
|
||||||
# Lendo as tags de automationpattern (caso existam)
|
# Lendo as tags de automationpattern (caso existam)
|
||||||
|
# caso não existam, seta um valor default
|
||||||
|
# (assim acontece para, basicamente, todas as tags)
|
||||||
for automationpattern in track.findall('./automationpattern'):
|
for automationpattern in track.findall('./automationpattern'):
|
||||||
automation_pattern_info = {
|
automation_pattern_info = {
|
||||||
'name': automationpattern.attrib.get('name', 'N/A'),
|
'name': automationpattern.attrib.get('name', 'N/A'),
|
||||||
|
|||||||
+179
@@ -0,0 +1,179 @@
|
|||||||
|
# Documentação do Arquivo .mmp (LMMS)
|
||||||
|
|
||||||
|
## `<lmms-project>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- `version` (**Obrigatório**) — Exemplos: `1.0`
|
||||||
|
- `type` (**Obrigatório**) — Exemplos: `song`
|
||||||
|
- `creator` (**Obrigatório**) — Exemplos: `LMMS`
|
||||||
|
- `creatorversion` (**Obrigatório**) — Exemplos: `1.2.2`
|
||||||
|
|
||||||
|
## `<head>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- `mastervol` (**Obrigatório**) — Exemplos: `100`
|
||||||
|
- `timesig_denominator` (**Obrigatório**) — Exemplos: `4`
|
||||||
|
- `bpm` (**Obrigatório**) — Exemplos: `140`
|
||||||
|
- `timesig_numerator` (**Obrigatório**) — Exemplos: `4`
|
||||||
|
- `masterpitch` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
|
||||||
|
## `<song>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- *(Sem atributos)*
|
||||||
|
|
||||||
|
## `<trackcontainer>`
|
||||||
|
- **Ocorrências**: 2
|
||||||
|
- **Atributos**:
|
||||||
|
- `width` (**Obrigatório**) — Exemplos: `700`, `600`
|
||||||
|
- `y` (**Obrigatório**) — Exemplos: `50`, `5`
|
||||||
|
- `minimized` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `type` (**Obrigatório**) — Exemplos: `bbtrackcontainer`, `song`
|
||||||
|
- `visible` (**Obrigatório**) — Exemplos: `1`
|
||||||
|
- `x` (**Obrigatório**) — Exemplos: `266`, `5`
|
||||||
|
- `maximized` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `height` (**Obrigatório**) — Exemplos: `400`, `300`
|
||||||
|
|
||||||
|
## `<track>`
|
||||||
|
- **Ocorrências**: 7
|
||||||
|
- **Atributos**:
|
||||||
|
- `type` (**Obrigatório**) — Exemplos: `5`, `0`, `1`
|
||||||
|
- `solo` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `muted` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `name` (**Obrigatório**) — Exemplos: `Automation track`, `Kicker`
|
||||||
|
|
||||||
|
## `<instrumenttrack>`
|
||||||
|
- **Ocorrências**: 3
|
||||||
|
- **Atributos**:
|
||||||
|
- `vol` (**Obrigatório**) — Exemplos: `100`
|
||||||
|
- `pitch` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `fxch` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `pitchrange` (**Obrigatório**) — Exemplos: `1`
|
||||||
|
- `basenote` (**Obrigatório**) — Exemplos: `57`
|
||||||
|
- `usemasterpitch` (**Obrigatório**) — Exemplos: `1`
|
||||||
|
- `pan` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
|
||||||
|
## `<instrument>`
|
||||||
|
- **Ocorrências**: 3
|
||||||
|
- **Atributos**:
|
||||||
|
- `name` (**Obrigatório**) — Exemplos: `audiofileprocessor`, `kicker`, `tripleoscillator`
|
||||||
|
|
||||||
|
## `<tripleoscillator>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos são **Obrigatórios** neste contexto (pois há uma única ocorrência)
|
||||||
|
- Exemplos incluem:
|
||||||
|
- `wavetype0`: `0`, `userwavefile0`: ``, `vol0`: `33`, `pan0`: `0`, `phoffset0`: `0`, etc.
|
||||||
|
|
||||||
|
## `<eldata>`, `<elvol>`, `<elcut>`, `<elres>`
|
||||||
|
- **Ocorrências**: 3 (cada)
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `att`: `0`, `dec`: `0.5`, `rel`: `0.1`, `lspd`: `0.1`, `userwavefile`: ``
|
||||||
|
|
||||||
|
## `<chordcreator>`
|
||||||
|
- **Ocorrências**: 3
|
||||||
|
- **Atributos**:
|
||||||
|
- `chordrange` (**Obrigatório**) — Exemplos: `1`
|
||||||
|
- `chord-enabled` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `chord` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
|
||||||
|
## `<arpeggiator>`
|
||||||
|
- **Ocorrências**: 3
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `arp`: `0`, `arpdir`: `0`, `arpgate`: `100`
|
||||||
|
|
||||||
|
## `<midiport>`
|
||||||
|
- **Ocorrências**: 3
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `inputchannel`: `0`, `outputchannel`: `1`
|
||||||
|
|
||||||
|
## `<fxchain>`
|
||||||
|
- **Ocorrências**: 5
|
||||||
|
- **Atributos**:
|
||||||
|
- `enabled` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
- `numofeffects` (**Obrigatório**) — Exemplos: `0`
|
||||||
|
|
||||||
|
## `<sampletrack>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- `vol`, `pan` (**Obrigatórios**) — Exemplos: `100`, `0`
|
||||||
|
|
||||||
|
## `<bbtrack>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- *(Sem atributos)*
|
||||||
|
|
||||||
|
## `<kicker>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos são **Obrigatórios**
|
||||||
|
- Exemplos: `decay`: `440`, `dist`: `0.8`, `startfreq`: `150`
|
||||||
|
|
||||||
|
## `<pattern>`
|
||||||
|
- **Ocorrências**: 2
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `steps`: `16`, `name`: `Kicker`, `clap04.ogg`
|
||||||
|
|
||||||
|
## `<note>`
|
||||||
|
- **Ocorrências**: 5
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `key`: `57`, `vol`: `100`, `len`: `-192`
|
||||||
|
|
||||||
|
## `<audiofileprocessor>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `src`: `drums/clap04.ogg`, `looped`: `0`, `reversed`: `0`
|
||||||
|
|
||||||
|
## `<bbtco>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `name`: ``, `pos`: `0`, `len`: `192`
|
||||||
|
|
||||||
|
## `<automationtrack>`
|
||||||
|
- **Ocorrências**: 2
|
||||||
|
- *(Sem atributos)*
|
||||||
|
|
||||||
|
## `<automationpattern>`
|
||||||
|
- **Ocorrências**: 5
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `name`: `Tempo`, `len`: `192`, `prog`: `0`
|
||||||
|
|
||||||
|
## `<fxmixer>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `width`: `543`, `height`: `333`, `visible`: `1`
|
||||||
|
|
||||||
|
## `<fxchannel>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `name`: `Master`, `volume`: `1`
|
||||||
|
|
||||||
|
## `<ControllerRackView>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `width`: `350`, `visible`: `1`
|
||||||
|
|
||||||
|
## `<pianoroll>`, `<automationeditor>`, `<projectnotes>`
|
||||||
|
- **Ocorrências**: 1 (cada)
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `visible`: `0`, `width`: `860`
|
||||||
|
|
||||||
|
## `<timeline>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- **Atributos**:
|
||||||
|
- Todos **Obrigatórios**
|
||||||
|
- Exemplos: `lp0pos`: `0`, `lp1pos`: `192`
|
||||||
|
|
||||||
|
## `<controllers>`
|
||||||
|
- **Ocorrências**: 1
|
||||||
|
- *(Sem atributos)*
|
||||||
+512
@@ -0,0 +1,512 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
elementFormDefault="qualified">
|
||||||
|
|
||||||
|
<!-- Raiz do projeto -->
|
||||||
|
<xs:element name="lmms-project">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="head" type="HeadType" />
|
||||||
|
<xs:element name="song" type="SongType" />
|
||||||
|
<xs:element name="fxmixer" type="FxMixerType" minOccurs="0" />
|
||||||
|
<xs:element name="ControllerRackView" type="SimplePanelType" minOccurs="0" />
|
||||||
|
<xs:element name="pianoroll" type="SimplePanelType" minOccurs="0" />
|
||||||
|
<xs:element name="automationeditor" type="SimplePanelType" minOccurs="0" />
|
||||||
|
<xs:element name="projectnotes" type="SimplePanelType" minOccurs="0" />
|
||||||
|
<xs:element name="timeline" type="TimelineType" minOccurs="0" />
|
||||||
|
<xs:element name="controllers" type="ControllersType" minOccurs="0" />
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="version" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="type" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="creator" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="creatorversion" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- Cabeçalho do projeto -->
|
||||||
|
<xs:complexType name="HeadType">
|
||||||
|
<xs:attribute name="bpm" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="timesig_numerator" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="timesig_denominator" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="mastervol" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="masterpitch" type="xs:integer" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- SongType (RAÍZ) -->
|
||||||
|
<xs:complexType name="SongType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- Container de trilhas -->
|
||||||
|
<xs:element name="trackcontainer">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="track" type="TrackType" maxOccurs="unbounded" />
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="type" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="x" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="y" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="width" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="height" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="visible" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="minimized" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="maximized" type="xs:boolean" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- Trilhas -->
|
||||||
|
<xs:complexType name="TrackType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="type" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="muted" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="solo" type="xs:boolean" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- FxMixerType -->
|
||||||
|
<xs:complexType name="FxMixerType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="fxchannel" type="FxChannelType" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="minimized" type="xs:boolean" />
|
||||||
|
<xs:attribute name="maximized" type="xs:boolean" />
|
||||||
|
<xs:attribute name="height" type="xs:integer" />
|
||||||
|
<xs:attribute name="y" type="xs:integer" />
|
||||||
|
<xs:attribute name="x" type="xs:integer" />
|
||||||
|
<xs:attribute name="visible" type="xs:boolean" />
|
||||||
|
<xs:attribute name="width" type="xs:integer" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- FxChannelType -->
|
||||||
|
<xs:complexType name="FxChannelType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="fxchain" type="FxChainType" minOccurs="0" maxOccurs="1" />
|
||||||
|
<xs:element name="send" type="SendType" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="muted" type="xs:boolean" />
|
||||||
|
<xs:attribute name="num" type="xs:integer" />
|
||||||
|
<xs:attribute name="volume" type="xs:decimal" />
|
||||||
|
<xs:attribute name="soloed" type="xs:boolean" />
|
||||||
|
<xs:attribute name="name" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- FxChainType -->
|
||||||
|
<xs:complexType name="FxChainType">
|
||||||
|
<xs:attribute name="enabled" type="xs:boolean" />
|
||||||
|
<xs:attribute name="numofeffects" type="xs:integer" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- SendType -->
|
||||||
|
<xs:complexType name="SendType">
|
||||||
|
<xs:attribute name="channel" type="xs:integer" />
|
||||||
|
<xs:attribute name="amount" type="xs:decimal" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- Trilha de instrumento -->
|
||||||
|
<xs:element name="instrumenttrack">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="vol" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="pan" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="pitch" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="fxch" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="basenote" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="usemasterpitch" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="pitchrange" type="xs:integer" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- Pattern -->
|
||||||
|
<xs:element name="pattern">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="note" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="pan" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="pos" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="key" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="vol" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="len" type="xs:integer" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="muted" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="steps" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="type" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="pos" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- automationtrack -->
|
||||||
|
<xs:element name="automationtrack">
|
||||||
|
<xs:complexType/>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- automationpattern -->
|
||||||
|
<xs:element name="automationpattern">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="mute" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="prog" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="pos" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="tens" type="xs:integer" use="required"/>
|
||||||
|
<xs:attribute name="len" type="xs:integer" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- sampletrack -->
|
||||||
|
<xs:element name="sampletrack">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="fxchain" minOccurs="1" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="enabled" type="xs:int" use="required"/>
|
||||||
|
<xs:attribute name="numofeffects" type="xs:int" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="pan" type="xs:int" use="required"/>
|
||||||
|
<xs:attribute name="vol" type="xs:int" use="required"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- Instrumento TEM QUE VERIFICAR -->
|
||||||
|
<xs:element name="name">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element name="audiofileprocessor">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="eframe" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="stutter" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="looped" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="interp" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="reversed" type="xs:boolean" use="required" />
|
||||||
|
<xs:attribute name="lframe" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="src" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="amp" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="sframe" type="xs:integer" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="kicker">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="decay" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="gain" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="slope" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="endfreq" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="startfreq" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="version" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="dist" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="click" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="distend" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="env" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="endnote" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="startnote" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="decay_numerator" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="decay_syncmode" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="decay_denominator" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="noise" type="xs:decimal" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="tripleoscillator">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="pan0" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="phoffset1" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="modalgo2" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="vol0" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="wavetype1" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="userwavefile2" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="phoffset2" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="modalgo1" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="finer0" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="finer1" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="finer2" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="coarse1" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="stphdetun0" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="stphdetun1" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="modalgo3" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="pan1" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="finel2" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="coarse0" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="userwavefile0" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="userwavefile1" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="stphdetun2" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="finel1" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="vol2" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="pan2" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="finel0" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="vol1" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="phoffset0" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="coarse2" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="wavetype0" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="wavetype2" type="xs:integer" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="BitinvaderType">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="sampleLength" type="xs:integer" use="required" />
|
||||||
|
<xs:attribute name="version" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="sampleShape" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="interpolation" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="normalize" type="xs:integer" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="PapuType">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="ch4vsd" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch1wpd" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch1so2" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch1ssl" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="Treble" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="sd" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch2wpd" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch3so2" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="srs" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch2vol" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch1vsd" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch4so2" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch1so1" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="srw" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch2vsd" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch3so1" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch4ssl" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="st" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch1vol" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch2so1" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch4so1" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="sampleShape" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="ch2so2" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="Bass" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch3vol" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch2ssl" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="so1vol" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="ch4vol" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="so2vol" type="xs:integer" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="GigplayerType">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="patch" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="src" type="xs:string" use="optional" />
|
||||||
|
<xs:attribute name="gain" type="xs:decimal" use="optional" />
|
||||||
|
<xs:attribute name="bank" type="xs:integer" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="Lb302Type">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="vcf_dec" type="xs:decimal" use="optional" />
|
||||||
|
<xs:attribute name="vcf_mod" type="xs:decimal" use="optional" />
|
||||||
|
<xs:attribute name="slide" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="dist" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="slide_dec" type="xs:decimal" use="optional" />
|
||||||
|
<xs:attribute name="dead" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="vcf_cut" type="xs:decimal" use="optional" />
|
||||||
|
<xs:attribute name="vcf_res" type="xs:decimal" use="optional" />
|
||||||
|
<xs:attribute name="shape" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="db24" type="xs:integer" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="MalletsstkType">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="vib_freq" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="preset" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="velocity" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="vib_gain" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="spread" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="lfo_speed" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="version" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="stick_mix" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="adsr" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="hardness" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="oldversion" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="modulator" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="lfo_depth" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="pressure" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="strike" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="crossfade" type="xs:integer" use="optional" />
|
||||||
|
<xs:attribute name="position" type="xs:integer" use="optional" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="watsyn">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="a1_pan" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envDec" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a2_rtune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="amod" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b1_vol" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b2_pan" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="abmix" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="xtalk" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a1_wave" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="a1_rtune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envHold" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b2_vol" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b2_mult" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a1_vol" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a2_ltune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="bmod" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b1_mult" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envAtt" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envAtt_denominator" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envHold_numerator" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b2_ltune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b1_rtune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a1_mult" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a2_vol" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a2_pan" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envDec_numerator" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envDec_syncmode" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envDec_denominator" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envAmt" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b2_wave" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="envHold_syncmode" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a2_mult" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b2_rtune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a2_wave" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="envAtt_syncmode" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envAtt_numerator" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b1_ltune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envHold_denominator" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="a1_ltune" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b1_pan" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="b1_wave" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="vibedstrings">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="pick0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active6" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active7" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="octave0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="impulse0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active4" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="version" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="active5" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="detune0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="slap0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="volume0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="pickup0" type="xs:decimal" use="required" />
|
||||||
|
<xs:attribute name="active8" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="stiffness0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="pan0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="graph0" type="xs:string" use="required" />
|
||||||
|
<xs:attribute name="length0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="active3" type="xs:int" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="vestige">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="plugin" type="xs:string" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="sid">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="pulsewidth2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="release0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="ringmod2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="filterResonance" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="attack0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="filtered0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="chipModel" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="waveform0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sustain0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="attack2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="ringmod1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sync1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="release2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="filtered1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="release1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="waveform2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="voice3Off" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="pulsewidth1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sustain1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="test0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sync0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sync2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sustain2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="coarse2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="decay2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="coarse0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="ringmod0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="volume" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="filtered2" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="filterMode" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="waveform1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="decay0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="decay1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="pulsewidth0" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="voice1Off" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="coarse1" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="voice2Off" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="attack1" type="xs:int" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<xs:element name="analo4">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="freq" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sweep" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envAmt" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="cutoff" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="mod" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envDec" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="res" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="decay" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envAtt" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="attack" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sweepDepth" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="sustain" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="vol" type="xs:int" use="required" />
|
||||||
|
<xs:attribute name="envHold" type="xs:int" use="required" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
|
||||||
|
<!-- Tipos simples para painéis -->
|
||||||
|
<xs:complexType name="SimplePanelType">
|
||||||
|
<xs:attribute name="height" type="xs:integer" />
|
||||||
|
<xs:attribute name="y" type="xs:integer" />
|
||||||
|
<xs:attribute name="x" type="xs:integer" />
|
||||||
|
<xs:attribute name="visible" type="xs:boolean" />
|
||||||
|
<xs:attribute name="width" type="xs:integer" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="TimelineType">
|
||||||
|
<xs:attribute name="height" type="xs:integer" />
|
||||||
|
<xs:attribute name="y" type="xs:integer" />
|
||||||
|
<xs:attribute name="x" type="xs:integer" />
|
||||||
|
<xs:attribute name="visible" type="xs:boolean" />
|
||||||
|
<xs:attribute name="width" type="xs:integer" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="ControllersType">
|
||||||
|
<xs:attribute name="height" type="xs:integer" />
|
||||||
|
<xs:attribute name="y" type="xs:integer" />
|
||||||
|
<xs:attribute name="x" type="xs:integer" />
|
||||||
|
<xs:attribute name="visible" type="xs:boolean" />
|
||||||
|
<xs:attribute name="width" type="xs:integer" />
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
</xs:schema>
|
||||||
Reference in new issue
Block a user