/* ------------------- T O P S E C R E T C O D E S T A R T S . . . H E R E ! ATT FIXA: rensa koden på variabler som inte behövs ta bort all debug problemet är att den inte hittar rätt peak - ta bort RMS:en och lägg in en envfollower istället - nu hittar den rätt peak men prelayen verkar vara åt fanders - ändradee några env till in i Hitta samplingarna vilket (kanske?) fixade prelayen - ytterligare ett problem var hysterisis som ju blir rätt beroende av releasen på env, kanske bara ska ta bort hysterisen helt och hållet? Eller minska den rejält? gör en fadeout/fade då en sampling måste ersättas av en annan så det inte klickar (eller låt DrumReaplacer välja hur många röster som ska användas...) testa att ändra pdc istället för prelay (ev i kombination med en max_prelay så den inte känns saggig) en smartare laddgrej (så den inte låser hela reaper) borde den randoma lite då den varierar vlken sample det ska bli? så det inte blir ett mönster i't (typ 1,2,3,1,2,3 osv) frigör minne ifall man laddar en mindre sampling efter en större se till att användaren inte kan ändra No of samples found och Status Gör en effektivare downsampling Stealth mode (skriv samplingarna till en variabel istället för till spl0 och 1 och gör typ en kompressor i slutet) Ska den automatiskt sträcka ut dynamiken ifall den starkaste samplingen inte är särskilt stark? gör det till ett val att splitta med thresholds åxå FIXAT: (- verkar vara det, peaken blir på samma ställe varje gång lös det problemet - testar att sänka rmsen till en sampling, dvs man skulle inte behöva nån rms egentligen funkar med vissa samplingar, men inte med alla t ex (hi tom...)) För att fixa nedan fuländrar den bara prelayen utan hänsyn till hur det låter. Men det fubnkar: kolla så att prelayen inte är längre än pdc:n (+ vad det nu är) och i så fall ändra pdc:n - (IDÉ! Man skulle kunna göra en max tid från start till max_pos) Varför blir det tyst ibland när man drar upp Dynamics? - för att sampling no 1 fick en toklång prelay som inte rymdes inom pdcn ändra så att threshold startar på 0 db istället för -18 db ändra skalan på opriginal signal och replaced till 0-200% Lägg in en spärr så man inte kan ladda för stora samplingar (max = 8388607 värden) testa hur hög max_wait ska va 30ms 50ms? Kalibrerat max_wait (gjort den lägre) hysterisis (ökat den) och rms fönstret (gjort det lite mindre) så den sätter samplingarna mycket bättre Kolla hur stora filer man kan ladda (8388607 värden) lägg slajdrarna i rätt ordning En dynamics slider fixa så den inte hittar för många samplingar då man laddar en liten efter en stor - ändrade slut villkoret från buf_size till conv_nånting_end Bygg ihop m trigger och samplingshittar-delen KOlla att kollen att srate inte är 0 (så den inte hänger sig om man laddar en sampling då srate är = 0) funkar Gör en bra SRC... hur? Gör den när samplingarna tankas in iaf (och måste läsas in igen om srate ändr as) Titta över (skriv om?) samplingsseparatorn, kolla på den som redan finns separera max_wait och retrigger (asså gör en riktig retrigger) Fixa minnesanvändningen: lägge variabler i botten och ljude ovanför Lägg max waiten på slider Gör en slider för samplingarnas styrka (som original mix), typ replaced signal Gör Round robin Kirrat, gjorde en buffer för voice_strength - Gör så den anpassar samplingens styrka efer slagets Verkar inte vara så längre - Varför hittar den olika spl_max om man laddar samma sampling flera gånger? (spelar det nån roll, asså hur stor är skillnaden?)Kolla att valet av sampling stämmer Nu funka auto-spliten med digital tystnad Gör så den väljer rätt sampling att ersätta med Gör sortera samplingarna grejen gÖR EN RETRIGGER INTERVAL - ökade bara max_waiten, borde den ligga på slider? Se till att prelayen funkar låt den slumpa en samplin och triga den rätt BLÄÄÄÄ! Det var för att jag hade dragit ut en sampling som loopade, när jag Glueade den så funkar allt som väntat... Kolla varför detectorn ibland missat slag som är identiska som andra slag den hittar... - det är trigger som missar, inte uppspelaren - olika värden på olika slag oavsett rms - ska man göra en open/close grej... fler trig_mode asså OK - det verkar som att prelayen funkar rätt (fast den är hälften så lång som slider visar... men så ska det nog vara) - då måste det ju vara spl_prelay värdena på spl 2 och uppåt som är på tok LÖST! Det blev helt bisarrt stora prelayvärden, strööe än global_pdc och då funknar det ju int. nu har jag ändrat global PDC till 1 sekund och då funkar det IDÉ! Man skulle kunna göra en max tid från start till max_pos delaya ljudet och fixa pdc Gör hit detection svängen på input Gör ytterligare en rms i sample detect svängen, en som har samma storlek som den i hit detection (kolla i gamla replacern) det var kvar skräp i buffrarna - Nu hittar den rätt antal samplingar, men visar (ibland) fel tills man trycker play Kolla att alla samplingar låter (verkar så nu...) flyttade slutpunkten till mellan de två RMS:erna som jämförs > KOlla varför det kommer ett litet klick i slutet av samplingarna (ibland?) ext_noinit=1 fixade det > Varför blir det MAX ksräp när man förtsa gången sätter på play och triggar en sampling? Byt till en annan och byt tbka så funkar det... Stämmer latencyn eller måste den omräknas ifall samplingsfrekvenserna inte stämmer? Räkna om tror jag, gångra med srate / file_srate fil threshold replaced signal original signal dynamics retrig force variation stealth meter - no of samples found meter - Output sample status 1-1 fil 2 7-3 threshold 9-4 retrig 10-5 dynamics 8-6 force variation 3-7 no of voices 8 4-9 original signal 5-10 replaced signal --11 stealth 6-13 meter - no of samples found 12-14 meter - Output sample --15 status */ desc:DrumReaplacer 1.09 slider1:/DrumReaplacer:none:Sample source file slider3:0<-50,0,0.1>Threshold (dB) slider4:80<0,200,1>Retrigger interval (ms) slider5:0<-100,100,1>Dynamics (%) slider6:20<0,100,1>Force variation (%) slider7:2<1,5,1>Voices slider9:0<0,200,1>Original signal (%) slider10:100<0,200,1>Replaced signal (%) slider13:0<1,64,1>Meter: Samples found slider14:0<0,64,1>Meter: Output sample slider15:1<1,3,1{File loaded OK,No file loaded,File too large,Loading file...}>Status //slider16:0<0,64,1>Debug @init max_memory = 8388607; //max antal värden i det lokala minnet safety_margin = 1000; //säkerhetsmarginal max_memory -= safety_margin; ext_noinit = 1; next_voice = 1; max_no_of_voices = 5; scale = log( 10.0 ) * 0.05; // precalculate this once hit_rms_window = 0.001; //rms:ens storlek i s hysterisis = 1.5; trig_mode = 0; max_wait = 10 * 0.001 * srate; //sök högsta peak X ms efter att threshold passerats global_pdc = floor( srate * 0.100 + max_wait ); //fördröj allting en stund och kompensera för det pdc_delay = global_pdc; pdc_bot_ch = 0; pdc_top_ch = 2; //kompensera bara ljudkanal 1 o 2 audio_bufsize = global_pdc * 2; //*2 för att det ju är stereo min_silence = ceil( srate / 20 ); //hur långt det måste vara mellan samplingarna rel_db = 25; //envelope release i dB per sekund rel = exp( rel_db * scale ) / srate; //-------------------------- S L I D E R @slider dynamics = ( slider5 + 100 ) / 100; threshold = exp( slider3 * scale ); cl_threshold = exp( ( slider3 - hysterisis ) * scale ); retrig_interval = slider4 * 0.001 * srate; //sök högsta peak X ms efter att threshold passerats no_of_voices = slider7; original_signal = slider9 / 100; replaced_signal = slider10 / 100; tmpslider = slider1|0; //ska det vara |0? tmpslider != prev_slider1 ? ( prev_slider1 = tmpslider; filehandle = file_open(slider1); filehandle > 0 && srate != 0 ? ( file_riff( filehandle, nch, file_srate ); //kolla srate & antal kanaler nch ? buf_size = file_size = file_avail( filehandle ) ; //kolla hur stor den är nch_add = floor( nch / 2 ); //-------------------------- G E P L A T S I M I N N E T bufpos = 0; voice_on = bufpos + max_no_of_voices + 1; spldet_rms = voice_on + no_of_voices + 1; //ge plats i minnet memset( spldet_rms, 0, spldet_rms_size ); //rensar spl_start = spldet_rms + spldet_rms_size + 1; spl_end = spl_start + 64 + 1; //stödjer upp till 64 samplingar m andra ord spl_max = spl_end + 64 + 1; spl_prelay = spl_max + 64 + 1; spldet_rms_buf = spl_prelay + 64 + 1; //buffrar rmsen så man kan jämföra före och efter memset( spldet_rms_buf, 0, spldet_rms_size ); //rensar voice_sample = spldet_rms_buf + spldet_rms_size + 1; hit_rms_buf = voice_sample + 16 + 1; //upp till 16 röster då hit_rms_sz_file = floor( hit_rms_window * srate ); hit_rms_sz_proj = floor( hit_rms_window * srate ); //nästa buffer borde börja så att hit_rms_buf har utrymme att funka upp 96kHZ audio_buf = hit_rms_buf + floor( hit_rms_window * 96000 ) + 1; trig_buf = audio_buf + audio_bufsize + 2; memset( trig_buf, 0, audio_bufsize ); voice_strength = trig_buf + audio_bufsize + 2; rr_buf = voice_strength + 16 + 1; memset( rr_buf, 0, 16 ); //------------------------------ M e m o r y c h e c k file_too_large = 0; file_srate > srate && ( rr_buf + 16 + 1 + 80 + file_size * ( srate / file_srate ) ) > max_memory ? file_too_large = 1; //Downsampling MC file_srate == srate && ( rr_buf + 16 + 1 + file_size ) > max_memory ? file_too_large = 1; //No resampling MC file_srate < srate && ( rr_buf + 16 + 1 + file_size * ( srate / file_srate ) ) > max_memory ? file_too_large = 1; //Upsampling MC file_too_large == 0 && slider1 == 0 ? ( slider15 = 1; sliderchange( slider15 ); no_of_samples = 0;); //om första filen (choose file...) är vald, skriv no file loaded och speal inte upp nåt // file_too_large == 0 && slider1 != 0 ? ( slider15 = 3; sliderchange( slider15 ); ); //om filen inte är för stor och det inte är första filen, skriv File loaded OK file_too_large == 1 ? ( slider15 = 2; sliderchange( slider15 ); //skriver file too large no_of_samples = 0; //ser till att det inte spelas upp nåt slider13 = 0; sliderchange( slider13 ); //skriver samples found 0 ); file_too_large != 1 ? ( //------------------------------ S R C //Nersampling i mono och stereo funkar nu bra men tar jääättelång tid. Var den snabbare förut? //Samma srate funkar finfint //Uppsampling funkar finfint //------------------------------ D o w n s a m p l i n g file_srate > srate ? ( temp_start_pos = rr_buf + 16 + 1; //här börjar ljudfilssnuttarna i minnet start_pos = temp_start_pos + 80; //utrymme för temp... sen börjar den konverterade ljudfilen last_read_pos = conv_pos = tmp_total = tmp_total_R = exact_pos = 0 ; step = file_srate / srate ; while ( while ( exact_pos += step; file_mem( filehandle, temp_start_pos, ( ceil( exact_pos ) - last_read_pos ) * nch ); //läs in en snutt samples_read = ( ceil( exact_pos ) - last_read_pos ) * nch; //så mycket läste jag in last_read_pos = ceil( exact_pos ); //spara senast inlästa position i last_read_pos //Här läser man in alla "hela" samplingar (utom den sista) tmp_pos = 0; samples_read > nch ? ( loop( ( ( samples_read - nch ) / nch ) , tmp_total += temp_start_pos[ tmp_pos ]; nch > 1 ? tmp_total_R += temp_start_pos[ tmp_pos + 1 ]; tmp_pos += nch; ); ); part = exact_pos - floor( exact_pos ); //Så stor del av den sista inlästa samplingen som ska med i den konverterade samplingen tmp_total += temp_start_pos[ tmp_pos ] * part; //lägg till det i tmp_total nch > 1 ? tmp_total_R += temp_start_pos[ tmp_pos + 1 ] * part; //lägg till det i tmp_total_R (höger kanal) om det är stereo start_pos[ conv_pos ] = tmp_total / step; //och skriv till den konverterade samplingen nch > 1 ? start_pos[ conv_pos + 1 ] = tmp_total_R / step; conv_pos += nch; tmp_total = temp_start_pos[ tmp_pos ] * ( 1 - part ); //flytta det som "blev över" till tmp_total så det kommer med i nästa konverterade sampling tmp_total_R = temp_start_pos[ tmp_pos + 1 ] * ( 1 - part ); last_read_pos + step < file_size ; //egentligen en fuling, den kan ju missa lite, lite information i slutet ); last_read_pos + step < file_size ; //dubbla while för att filen kan vara större än max för en while (typ en miljon) ); conv_file_end = conv_pos; file_close(filehandle); //och stänger filen ); //sluter downsamplingen //-------------------------------- U p s a m p l i n g file_srate < srate ? ( start_pos = rr_buf + 16 + 1; //här börjar den konverterade filen så småningom temp_start_pos = ceil( ( ( srate / file_srate ) * buf_size ) + start_pos - buf_size ) ; //lägger temp_pos så den okonverterade filen slutar på samma ställe som den konverterade sen ska göra file_mem( filehandle, temp_start_pos, buf_size ); //läser in filen step = file_srate / srate; conv_pos = exact_pos = 0; //mono nch == 1 ? ( while ( while ( tmp = exact_pos - floor( exact_pos ); start_pos[ conv_pos ] = ( temp_start_pos[ floor( exact_pos ) ] * ( 1 - tmp ) ) + ( temp_start_pos[ ceil( exact_pos ) ] * tmp ); //lägg ihop dem exact_pos += step; conv_pos += 1; exact_pos < buf_size; ); exact_pos < buf_size; ); ):( //stereo buf_size_div_by_2 = buf_size / 2; while ( while ( tmp = exact_pos - floor( exact_pos ); start_pos[ conv_pos ] = ( temp_start_pos[ floor( exact_pos ) * 2 ] * ( 1 - tmp ) ) + ( temp_start_pos[ ceil( exact_pos ) * 2 ] * tmp ); //lägg ihop dem start_pos[ conv_pos + 1 ] = ( temp_start_pos[ ( floor( exact_pos ) * 2 ) + 1 ] * ( 1 - tmp ) ) + ( temp_start_pos[ ( ceil( exact_pos ) * 2 ) + 1 ] * tmp ); //lägg ihop dem exact_pos += step; conv_pos += 2; exact_pos < buf_size_div_by_2 ; ); exact_pos < buf_size_div_by_2 ; ); ); conv_file_end = conv_pos - 1; file_close(filehandle); //och stänger filen ); //sluter upsamplingen //----------------------------------- N o r e s a m p l i n g file_srate == srate ? ( start_pos = rr_buf + 16 + 1; file_mem( filehandle, start_pos, buf_size ); //läs in filen file_close(filehandle); //och stäng filen conv_file_end = buf_size; ); //sluter ingen resampling //--------------------------------- T H E E N D O F S R C ( a s w e k n o w i t ) //-------------------------- H I T T A S A M P L I N G A R N A -------------------------------------------- // Allt det här borde dras in två steg till vänster men... spldet_read_pos = spldet_since_new = hit_rms_pos = hit_rms_tot = spldet_z_in_row = time_in_mode_1 = 0; no_of_samples = 0; spl_start[ 1 ] = 0; spl_end[ 1 ] = buf_size; spl_max[ 1 ] = 0; //här borde spl_max nollas (eftersom värdena jämförs med tidigare för att hitta max) memset( spl_max, 0, 64 ); find_mode = 0; //0 = bara i början, väntar på nåt annat än noll, 1 = väntar på X antal nollor, 2 = väntar på nåt annat än noll //dubbla while för att gränsen för en while är typ 1 miljon och filerna kan ju ha fler samples än så while( while( //Envelope in = max( abs( start_pos[ spldet_read_pos ] ), abs( start_pos[ spldet_read_pos + nch_add ] ) ); env = in > env ? in : max( env - rel, in ); find_mode == 0 ? ( //de två sista ("spldet_since_new = 0; spl_start [ 1 ] = spldet_read_pos;") nedan för att spl no 1 annars får jättelång prelay (längre än pdc) env != 0 ? ( find_mode = 1; no_of_samples += 1; spldet_since_new = 0; spl_start [ 1 ] = spldet_read_pos; ); ); find_mode == 1 ? ( time_in_mode_1 > min_silence ? ( in == 0 ? spldet_z_in_row += 1 : spldet_z_in_row = 0; spldet_z_in_row > min_silence ? ( spl_end[ no_of_samples ] = spldet_read_pos - min_silence; find_mode = 2; time_in_mode_2 = 0; spldet_z_in_row = 0; ); ); env > spl_max[ no_of_samples ] ? ( spl_max[ no_of_samples ] = env; spl_prelay[ no_of_samples ] = spldet_since_new; ); time_in_mode_1 += 1; ); //sluter find_mode == 1 find_mode == 2 ? ( in != 0 ? ( tmp_start = spldet_read_pos; time_in_mode_2 > min_silence ? ( find_mode = 1; time_in_mode_1 = 0; //nollar den inför nästa sample no_of_samples += 1; spl_start[ no_of_samples ] = tmp_start ; spl_end[ no_of_samples ] = buf_size; //ifall inget slut hittas spl_max[ no_of_samples ] = 0; spldet_since_new = 0; ); ); time_in_mode_2 += 1; ); //sluter find_mode == 2 spldet_since_new += 1; spldet_read_pos += ( 1 + nch_add ); spldet_read_pos < conv_file_end; //brukade vara buf_size - sluter första whilen ); spldet_read_pos < conv_file_end; //brukade vara buf_size - sluter andra whilen ); //--------------- Kollar så att prelayen inte är större än pdcn och justerar i så fall prelayen (man skulle ju kunna ndra pdcn istället men...) tmp = 1; loop( no_of_samples, //kollar så att prelayen på samplingen som just hittats inte är för stor spl_prelay[ tmp ] > global_pdc ? ( spl_start[ tmp ] = spl_start[ tmp ] + ( spl_prelay[ tmp ] - global_pdc - nch ) ; spl_prelay[ tmp ] = global_pdc - nch; ); tmp += 1; ); //--------------- Sortera samplingarna tmplap = 1; loop( no_of_samples, tmp = 1; tmpmax = 0; tmpmaxsplno = 0; loop( no_of_samples, spl_max[ tmp ] > tmpmax ? ( tmpmax = spl_max[ tmp ]; tmpmaxsplno = tmp; ); tmp += 1; ); tmpmaxsplno != tmplap ? ( //flytta det som ligger i den här vändans nummer (1, 2 osv) till tmp tmp_start = spl_start[ tmplap ]; tmp_end = spl_end[ tmplap ]; tmp_max = spl_max[ tmplap ]; tmp_prelay = spl_prelay[ tmplap ]; //flytta värdena för det starkaste slaget till vändans nummer spl_start[ tmplap] = spl_start[ tmpmaxsplno ]; spl_end[ tmplap] = spl_end[ tmpmaxsplno ]; spl_max[ tmplap] = spl_max[ tmpmaxsplno ] * -1; //negativt så det inte ska bli starkast nästa varv åxå spl_prelay[ tmplap] = spl_prelay[ tmpmaxsplno ]; //flytta det som tidigare låg i vändans nummer till det nummer där det starkaste slaget tidigare låg spl_start[ tmpmaxsplno ] = tmp_start ; spl_end[ tmpmaxsplno ] = tmp_end ; spl_max[ tmpmaxsplno ] = tmp_max ; spl_prelay[ tmpmaxsplno ] = tmp_prelay ; ):( spl_max[ tmplap ] *= -1; ); tmplap += 1; ); //göra spl_max positivt igen tmp = 1; loop( no_of_samples, spl_max[tmp] = ( spl_max[tmp] * -1 ) ; tmp += 1; ); //visa hur många samplingar du hittat på slider slider13 = no_of_samples; sliderchange( slider13 ); //Visa File loaded OK file_size > 3 && no_of_samples > 0 ? ( slider15 = 0; sliderchange( slider15 ); ); ); //sluter file_too_large != 1... ); ); //Round robin - se till att man inte kan sätta den slider högre än antalet samplingar - 1 old_rr = ceil( ( no_of_samples - 1 ) * ( slider6 / 100 ) ); rr_buf_size = old_rr - 1; //Nollställ rr_buffer om man ändrar slidern (så den inte "fastnar" på fel sampling) tmpslider = slider6; tmpslider != prev_slider6 ? ( tmp_counter = 1; loop( no_of_samples, spl_max[ tmp_counter ] < 0 ? spl_max[ tmp_counter ] += 10; tmp_counter += 1; ); memset( rr_buf, 0, 16 ); //nolla rr-buffern ); prev_slider6 = tmpslider; @block //-------------------------------------- S A M P L E ------------------------------------------------------------------ @sample //Delay audio_buf[ audio_buf_pos ] = spl0; audio_buf[ audio_buf_pos + 1 ] = spl1; trig_buf[ audio_buf_pos ] = trig_buf[ audio_buf_pos + 1 ] = -1; //Envelope in = max( abs( spl0 ), abs( spl1 ) ); env = in > env ? in : max( env - rel, in ); spl0 = spl1 = 0; //Trigger trig_mode == 0 && env > threshold ? ( trig_mode = 1; wait_for_higher = max_peak = 0 = th_close = 0; ); trig_mode == 1 ? ( env > max_peak ? ( max_peak = env ; max_peak_pos = audio_buf_pos; time_since_maxpeak = 0; ); env < cl_threshold ? th_close = 1; wait_for_higher > max_wait && th_close == 1 ? ( tmpfind = 1; tmpclosest = 10000000; //bara nåt som är större än största skillnaden loop( no_of_samples, abs( max_peak * dynamics - spl_max[ tmpfind ]) < tmpclosest ? ( tmpclosest = abs( max_peak * dynamics - spl_max[ tmpfind ]); tmpstrength = max_peak * dynamics / spl_max[ tmpfind ]; tmp_spl = tmpfind; ); tmpfind += 1; ); tmp_pos = max_peak_pos - spl_prelay[ tmp_spl ] * 2; tmp_pos < 0 ? tmp_pos = audio_bufsize + tmp_pos ; trig_buf[ tmp_pos ] = tmp_spl; trig_buf[ tmp_pos + 1 ] = tmpstrength ; //visa vilken sampling som spelas på slider14 slider14 = tmp_spl; sliderchange( slider14 ); //Round robin v2 rr_buf_size >= 0 ? ( spl_max[ rr_buf[ rr_bufpos ] ] += 10; spl_max[ tmp_spl ] -= 10; rr_buf[ rr_bufpos ] = tmp_spl; rr_bufpos += 1; rr_bufpos > rr_buf_size ? rr_bufpos = 0; ); trig_mode = 2; retrig_left = max( 0, ( retrig_interval - time_since_maxpeak - hit_rms_sz_proj ) ); ); ); trig_mode == 2 ? ( retrig_left < 1 ? trig_mode = 0; ); wait_for_higher += 1; time_since_maxpeak += 1; retrig_left -= 1; //Delay audio_buf_pos += 2; audio_buf_pos > audio_bufsize ? audio_buf_pos = 0; //flyttar fram ett snäpp så de äldsta värden ligger på audio_buf_pos-platsen spl0 += audio_buf[ audio_buf_pos ] * original_signal ; spl1 += audio_buf[ audio_buf_pos + 1] * original_signal ; //Check trig and manage voices tmp_trig = trig_buf[ audio_buf_pos ] ; tmp_trig != -1 && no_of_samples > 0 ? ( voice_sample[next_voice] = tmp_trig ; voice_strength[next_voice] = trig_buf[ audio_buf_pos + 1 ]; bufpos[next_voice] = spl_start[ tmp_trig ]; voice_on[next_voice] = 1; next_voice += 1; next_voice > no_of_voices ? next_voice = 1; ); //Play samples voice = 1; loop( no_of_voices, voice_on[voice] == 1 ? ( spl0 += start_pos[ bufpos[voice] ] * voice_strength[ voice ] * replaced_signal ; spl1 += start_pos[ bufpos[voice] + nch_add ] * voice_strength[ voice ] * replaced_signal ; //nch_add = 0 om det är mono, = 1 om det är stereo bufpos[voice] += 1 + nch_add; bufpos[voice] > spl_end [ voice_sample[ voice ] ] ? voice_on[voice] = 0; ); voice += 1; );