Se connecter
Se connecter

ou
Créer un compte

ou

Sujet Theorie d'un crossfade loop ?

  • 18 réponses
  • 4 participants
  • 1 143 vues
  • 3 followers
Sujet de la discussion Theorie d'un crossfade loop ?
Salut ! :D:
Comment ça marche un cross fade logiciel en theorie ? J'essaye de faire un algorithme pour relier deux samples wav mais impossible d'eviter le craquement du point de communtation. Quelqu'un connais la théorie ?
(ps : j'ai essayé de copier un bout du debut du deuxième son, de le mettre à l'envers, et de le coller à la fin du premier sample, le tout en jouant sur les les volumes pour passer d'un sample à l'autre mais rien n'y fait !
La sagesse, c'est la connaissance du vide.
2

Citation : Comment ça marche un cross fade logiciel en theorie ?



Je sais pas ce que c'est un crossfade, c'"est le fader des DJ pour passer d'une platine a l'autre (avec position au centre pour jouer les deux sons simultanement)...

Si c'est ca 'as juste besoin de joueur sur les volumes, pour un son tu fais une reduction du volume de type lineaire (ou au carré) et pour l'autre une augmentation du type lineaire (ou au carré)....

si ca craque c'est du a, mon avis a, autre chose. Tu bosses sur quoi poiur faire ca ?
3
J'ai programmé un pitch shift mais le systeme fonctionne en découpant des bouts d'echantillons et en les accolants entre pour pitch shifter. Mais des qu'on les accole, y a des points de commutation. (normal, ils ne sont plus à leur place) Donc faudrait passer d'un bout de sample à l'autre proprement.

En fait, mon but est de programmer un "acid" et un "sound forge" (light) en freeware.
La sagesse, c'est la connaissance du vide.
4

Hors sujet :

Citation : En fait, mon but est de programmer un "acid" et un "sound forge" (light) en freeware.



J'en ai rêvé, il va le faire.... :bravo:

5
Question très con (ahem désolé, il en faut) : est-ce que tu as bien pensé à ne coller les échantillons que sur un point 0 (i.e. quand ta valeur est à zéro) ? pcq moi j'ai souvenir d'en avoir déjà collé, et en cherchant un 0, je pense qu'il n'y avait pas de clic.
6
En fait le point zero ne pourrait être du qu'au hazard dans mon algorithme. Ce que j'ai essayé de faire pour l'instant est de faire un transition fade in/fad out proportionnels sur les deux samples, mais ça marche ne marche pas. Ca m'etonne d'ailleurs. Mais je vais quand meme réfléchir à l'idée du zero, bonne idée ! :bravo:
La sagesse, c'est la connaissance du vide.
7
Je comprend pas comment tu veux faire marcher ton truc...

si tu fais un fade in sur un sample, il commencera forcement a 0 puisque tu lui appliquera une enveloppe d'amplitude lineaire de type y(t)=a.x(t) :clin:

Question, t'as programmer ton algorithme sur quoi C, matlab, reaktor, max, Tu veux que je jetes un coup d'oeil :P:
8
En fait c'est du dark basic pro. Ce que je fait c'est que le "sample précent" est multiplié par un nombre à virgule alant de 1 à zero, et le "sample suivant" c'est l'inverse (0 à 1) mais quand je déforme le son avec le pitch sift, meme légèrement ça massacre le son. Voici le source :
(ps: tel que le programme est fait, il fait d'abord un pitch, puis un pitch shift inverse pour obtenir un time stretch)
(ps aussi : le forum tranforme les parenthese en smileys... faudra remplacer)

Citation : Rem Project: LoopArt
Rem Created: 22/08/2005 22:22:34

Rem ***** Main Source File *****

boucle:
print "Pitch shift ... Ok"
print "There are commutation noises. I've made a crossfade"
print "algorithm but it does not works."
print
input "speed (%) :",pourcent#
if pourcent#=0 then print "0 not accepted ..." : goto boucle


sync on
sync rate 0

open to read 1,"test.wav"
make memblock from file 10,1

chunksize = memblock dword(10,16)
datablocklength = memblock dword(10,40)
blocks2copy = datablocklength/chunksize

writeWAV(chunksize,blocks2copy,1)

close file 1

print "working...": sync : sync

rem = Prog principal: pour time strechter mon son, je le pitch, et je le pitchshift après
rem = dans l'autre sens. Ca ça marche.
rem = le premier paramètre est le memblock ou se trouve le wav et le 2eme
rem = est le memblock créé avec le nouveau wav. pourcent# est le pourcentage de pitch et
rem = datablocklength la taille du bloc de donnée récupérée sur le wav

if PitchMe(1,2,pourcent#,datablocklength)=0 then print "Pitch: Ok" else print "Sample size error"
delete memblock 1
print
print "working..." : sync
datablocklength = memblock dword(2,40)
if PitchShiftMe(2,1,pourcent#,datablocklength)=0 then print "Pitch shift applyed" else print "Pitch shift error"
sync : sync

if file exist("rendu.Wav")=1 then delete file "rendu.wav"
open to write 1,"Rendu.wav"
make file from memblock 1,1
close file 1

load sound "rendu.Wav",10
play sound 10
while sound playing(10)=1 : endwhile

delete memblock 10
delete memblock 2
delete memblock 1
delete sound 10

print "any key..." : sync : wait key

sync off
cls
goto boucle


function PitchMe(WavIn2 as integer, WavOut2 as integer, Pourcent# as float, dbl as integer)


header=44

b1s=dbl
b2s#=(b1s*(100.000/pourcent#))
if int(b2s#)>0
make memblock WavOut2,int(b2s#)+header
copy memblock WavIn2,WavOut2,0,0,header
write memblock dword WavOut2,40,int(b2s#)

p#=pourcent#/100.000
i=0
j#=p#*i

while i<int(b2s#/4.000)-4
value=memblock dword(WavIn2,(j#*4)+header)
write memblock dword WavOut2,header+(i*4),value
inc i
j#=p#*i
endwhile
else
exitfunction 1
endif
endfunction 0


function PitchShiftMe(WavIn as integer, WavOut as integer, Pourcent# as float ,dbl as integer)

popos as integer

header=44

Pourcent2#=(100.000/Pourcent#)*100.000

b1s=dbl
make memblock WavOut,get memblock size(WavIn)
copy memblock WavIn,WavOut,0,0,header

rem = Phase 1 = Je crée mon memblock de sortie (WavOut) je copie des petits morceaux de
rem = samples avec i et le memblock 95. Je pitch ensuite le memblock 95 dans le memblock
rem = 96 en sens inverse du pitch au debut du programme (pour pitch shifter à l'envers et
rem = obtenir mon time stretch. EchSize correspond à la taille d'un petit bout de son.
echsize=4410*2
make memblock 95,(echsize*4)
make memblock 96,(echsize*4*100.000)/Pourcent2#

for i=0 to b1s-(echsize*4) step (echsize*4)/2

copy memblock WavIn,95,header+i,0,(echsize*4)

rem pitch ---------------------------------------------------------------

p#=pourcent2#/100.000
i2=1
j2#=1.000+((i2-1)*p#)

while i2<(echsize)*(100.000/Pourcent2#)
k2=int(j2#)
copy memblock 95,96,(k2-1)*4,(i2-1)*4,4
inc i2
j2#=1.000+((i2-1)*p#)
endwhile

rem ============================================================================

rem = Phase 2: Assembler les petits bouts créés dans le fichier de sortie
rem = site un bout est trop grand je n'en prend qu'un partie, s'il est trop
rem = petit, il boucle (grace à j2)
rem = un fader est intégré pour enlever les points de commutation

j2=0
k2=0
FadeD=530
Pad#=1.00000000/FadeD
if i>0
rem = faut virer le rem start et le rem end pour réactiver les fades
rem = j'ai essayé de croiser les samples aussi en alternant un coup
rem = sur deux celui d'avant et celui d'après mais rien n'y fait.
remstart
fadeA#=1.00000000
fadeB#=0.00000000
else
remend
fadeA#=0.00000000
fadeB#=1.00000000
endif
while k2<(echsize)
value1=((memblock word(96,(j2*4)))*fadeB#)
value2=((memblock word(96,(j2*4)+2))*fadeB#)
value3=(memblock word(Wavout,header+(k2*4)+i+4)*fadeA#)
value4=(memblock word(Wavout,header+(k2*4)+i+6)*fadeA#)
if value1>65535 then value1=65535
if value2>65535 then value2=65535
if value3>65535 then value1=65535
if value4>65535 then value2=65535
write memblock word Wavout,header+(k2*4)+i,value1
write memblock word Wavout,header+(k2*4)+i+2,value2
write memblock word Wavout,header+(k2*4)+i+4,value3
write memblock word Wavout,header+(k2*4)+i+6,value4
inc j2,2
inc k2,2
if (j2*4)=>((echsize*4*100.000)/Pourcent2#)-4 then j2=0
rem = autre rem à virer pour réactiver les fades
rem if i>0 then fadeA#=fadeA#-pad# : fadeB#=fadeB#+pad#
if fadeA#<0 then fadeA#=0
if fadeA#>1 then fadeA#=1
if fadeB#<0 then fadeB#=0
if fadeB#>1 then fadeB#=1
endwhile
next i

delete memblock 95
delete memblock 96

endfunction 0



function writeWAV(chunksize as integer,blocks2copy as integer,Mnum as integer)
make memblock Mnum,(44+(chunksize*blocks2copy))
write memblock byte Mnum,0,asc("R")
write memblock byte Mnum,1,asc("I")
write memblock byte Mnum,2,asc("F")
write memblock byte Mnum,3,asc("F")
write memblock dword Mnum,4,((chunksize*blocks2copy)+(68-8)) `length of file - 8
write memblock byte Mnum,8,asc("W")
write memblock byte Mnum,9,asc("A")
write memblock byte Mnum,10,asc("V")
write memblock byte Mnum,11,asc("E")
write memblock byte Mnum,12,asc("f")
write memblock byte Mnum,13,asc("m")
write memblock byte Mnum,14,asc("t")
write memblock byte Mnum,15,asc(" ")
write memblock dword Mnum,16,16 `length of fmt data
write memblock word Mnum,20,1 `1=pcm
write memblock word Mnum,22,2 `1=mono 2=stereo
write memblock dword Mnum,24,44100 `sample rate
write memblock dword Mnum,28,176400 `sample rate * block align (this is bytes/second)
write memblock word Mnum,32,4 `channels * bits/sample / 8 (this is block align)
write memblock word Mnum,34,16 `8 or 16 (bits/sample)

write memblock byte Mnum,36,asc("d")
write memblock byte Mnum,37,asc("a")
write memblock byte Mnum,38,asc("t")
write memblock byte Mnum,39,asc("a")
write memblock dword Mnum,40,(chunksize*blocks2copy) `length of data block (divide by chunksize to get total chunks)
`starting from position 44 is the data block
`For multi-channel data, samples are interleaved between channels, like this:
`
`sample 0 for channel 0
`sample 0 for channel 1
`sample 1 for channel 0
`sample 1 for channel 1
`For Stereo audio 0 = left channel, 1= right channel
copy memblock 10,Mnum,44,44,chunksize*blocks2copy

endfunction

La sagesse, c'est la connaissance du vide.
9
Ok, j'ai pas tout compris :mdr: Mais bon je crois avoir mieux cerner le probleme...

tes algos de pitch time stretch sont basé sur de la synthèse granulaire je me trompe :?:
tu decoupe en petit grain que tu rassembles ensuite. L'algorithme tu l'as ramener d'ou (au niveau theorique) :?: La granulaire c'est bien (indépendance du temps et des fréquences) mais sur une console de DJ, ca se passe pas pareil, le temps et la fréquence ne sont pas indépendant....du coup si t'as un echantillon, en modifiant la vitesse de lecture de ton buffer (tout simplement comme si t'augmenter la vitesse de rotation de ta table de DJ) le son va egalement augmenter en hauteur...c'ets l'inverse si tu ralentis la lecture...Je suis loin d'etre un specialiste, mais pour ralentir,, il faut que t'interpolle


Citation : rem = Phase 2: Assembler les petits bouts créés dans le fichier de sortie
rem = site un bout est trop grand je n'en prend qu'un partie, s'il est trop
rem = petit, il boucle (grace à j2)
rem = un fader est intégré pour enlever les points de commutation




quand tu parles de fader, c'est bien d'enveloppe que tu parles....genres les click et tout appraissent lorsque tu boucles sur es grains...si tu met une enveloppe qui commence a 0 qui a son max a 1 et qui termine a 0; ca deconne quant même....en tout cas il faut pas esperer faire des mircale avec les algo de time stretch pitch shift...il ya toujours des pertes..

je sais pas si ca peut t'aider :??:
10
En fait, je me sert du bouquin "applications audio numériques des dsp" dans lequel cette technique est expliquée mais bon, ils parlent beaucoup plus de fourier, qui n'est pas assez rapide en basic malheureusement. Donc, là, dans le bouquin, y a un cd avec un code delphi mais je le comprend pas trop, alors j'ai suivi la théorie. Il appellent ça la "lecture à vitesse variable" et bon, pour le pitch shift c'est bon, j'ai pigé, mais pour leur "mécanisme de fondu enchainés", la théorie dit rien. Donc, le source comme le source delphi m'aide pas... tout ce que j'ai vu c'est qu'il utilise un tableau avec des sinus et cosinus prédéfinis qu'ils combinent avec les valeurs echantillonnés. Voici quelques lignes de code:

Citation : // Remplit les tables de fondu-enchainé
For I:=0 to (NbEchantillonsFondu-1) do begin
Angle:=(I*PI)/(2*NbEchantillonsFondu);
TableFonduIn^[I]:=cos(Angle);
TableFonduOut^[I]:=sin(Angle);
End;



et ...

Citation : // Prend les quatres échantillons (deux par ligne) pour l'interpolation
EchA1:=TamponRetard[IndexLectureA1];
EchA2:=TamponRetard[IndexLectureA2];
EchB1:=TamponRetard[IndexLectureB1];
EchB2:=TamponRetard[IndexlectureB2];

// Calcul de l'interpolation linéaire
If (TranspositionHaut) then begin
EchA:=(EchA2*Balayage)+(EchA1*(1-Balayage));
EchB:=(EchB2*Balayage)+(EchB1*(1-Balayage));
End
Else begin
EchA:=(EchA1*Balayage)+(EchA2*(1-Balayage));
EchB:=(EchB1*Balayage)+(EchB2*(1-Balayage));
End;

// Calcul de l'échantillon recombiné en sortie
Sortie:=Round((EchA*FonduA)+(EchB*FonduB));

La sagesse, c'est la connaissance du vide.