Forum Liberty Basic France

Général » Générateur BF Ou qui tente de l'être
Le 06/03/2016 à 09h18

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Reprise du message précédent

Je ne suis pas certain qu'il marche vraiment : l'intervalle de temps entre échantillons est plus petit, il y a moins d'écart d'amplitude à fréquence échantillonnée égale, et ça passe peut-être plus inaperçu à l'oreille...

J'ai laissé tomber les multiples car un ppcm ne peut être calculé qu'avec des entiers, et les périodes en 1/F sont très rarement entières. A la place je lance une série de calculs qui ne s'arrêtent que lorsque les signaux passent simultanément par zéro en montant, et quand ça arrive j'ai ma période globale, celle qui sera numérisée et reproduite autant de fois que nécessaire pour arriver à la durée souhaitée.

Sauf que, le dernier calcul donne 0, qui est le début de la période suivante, et si je base mon nombre d'échantillons sur ce calcul j'en ai un de trop. Et si je me trompe de signe, du genre +1 au lieu de -1, j'enregistre aussi l'échantillon suivant de la période d'après. Et lorsque je fais la concaténation, je me retrouve avec le petit pic qui dépasse 0, comme entouré sur l'image.

J'ai maintenant un autre souci : théoriquement j'efface le fichier wav à chaque fois que je clique sur "générer". Ca marche au premier lancement du programme : si le fichier wav existe alors il est effacé, et on génère le nouveau fichier. Par contre, si le programme est déjà lanceé, et que j'appuie une nouvelle fois sur "générer", le fichier n'est pas effaçé, mais les nouvelles données sont écrites après les données existantes. A un moment donné le transfert donne n'importe quoi...

Si c'est pas clair, voici le prog, si tu veux voir par toi-même (il n'y a que la génération 8 bits mono qui fonctionne):
Code VB :
 
'Géné BF 2 fréquences
'pour le moment, seule la génération 8bits mono fonctionne
'elle fonctionne mal puisqu'il semble que le fichier wav n'est pas effacé avant l'essai suivant
'reste à faire : barre de progression (_2.bas)
'                générateur morse (_3.bas) 'clin d'oeil à pmp^^

 
    'nomainwin

    NomWav$="pardefaut.wav"
    CheminWav$=DefaultDir$
 
    'dimensions de la fenêtre
    WindowWidth = 415
    WindowHeight = 495
 
    'formats d'affichage
    fonteGlobale$="font ms_sans_serif 0 16"
    fonteTitre$="!font ms_sans_serif 0 16 bold"
 
    'valeurs par défaut
    pi=3.1415926536
    freq1=880
    vol1=70
    freq2=440
    vol2=70
 
    duree=1
 
    'fréquences échantillonnage, Hz
    indexFech=1 'élément qui sera affiché dans la combobox
    FreqEch$(1)="11025"
    FreqEch$(2)="22050"
    FreqEch$(3)="44100"
 
    'résolution échantillonnage, bits
    indexRes=1
    WaveRes$(1)="8"
    WaveRes$(2)="16"
 
    'nombre de voies
    indexVoies=1
    WaveNbvoies$(1)="1-Mono"
    WaveNbvoies$(2)="2-Stereo"
 
    'création de l'interface utilisateur
    statictext #1.titreGen, "Générateurs :", 15, 15, 100, 20
 
    statictext #1.frequences, "Fréquence, Hz", 85, 40, 100, 20
    statictext #1.volumes, "Volume, 0 à 100", 195, 40, 100, 20
 
    statictext #1.gen1, "Gen. 1", 30, 65, 40, 20
    textbox #1.freq1, 80, 60, 100, 25
    textbox #1.vol1, 190, 60, 100, 25
 
    statictext #1.gen2, "Gen. 2", 30, 95, 40, 20
    textbox #1.freq2, 80, 90, 100, 25
    textbox #1.vol2, 190, 90, 100, 25
 
    statictext #1.sortie, "Fichier de sortie :", 15, 140, 125, 20
    statictext #1.nomWav, NomWav$, 140, 140, 390, 20
    button #1.changeDest, "Emplacement et nom du fichier", [changeDestination], UL, 30, 165, 350, 25
    statictext #1.cheminWav, CheminWav$, 30, 195, 300, 40
 
    statictext #1.param, "Paramètres du fichier Wave :", 15, 245, 200, 20
 
    statictext #1.fech, "Freq. échantillonnage, Hz", 30, 270, 170, 20
    combobox #1.comboEch, FreqEch$(), [f_echantillonnage], 210, 268, 75, 20
 
    statictext #1.fech, "Résolution, bits", 30, 300, 170, 20
    combobox #1.comboRes, WaveRes$(), [Wav_resolution], 210, 297, 75, 20
 
    statictext #1.fech, "Nombre de voies", 30, 330, 170, 20
    combobox #1.comboVoi, WaveNbvoies$(), [Wav_nombre_voies], 210, 328, 75, 20
 
    statictext #1.dureeWav, "Durée, s", 30, 360, 170, 20
    textbox #1.bxDureeWav, 210, 358, 75, 25
    'button #1.okDuree, "OK", [valide_duree], UL, 290, 360, 25, 25

    statictext #1.avanti, "En avant !", 15, 400, 270, 20
    button #1.genWav, "Générer", [genere_wav], UL, 30, 425, 80, 25
    button #1.annulCalc, "Annuler", [annule_calcul], UL, 120, 425, 80, 25
    button #1.quit, "Quitter", [quitter], UL, 300, 425, 80, 25
 
    'ouverture fenêtre d'interface utilisateur
    open "Géné. BF" for window as #1
 
        'fonte global
        print #1, fonteGlobale$
 
        'fonte titres
        print #1.titreGen, fonteTitre$
        print #1.sortie, fonteTitre$
        print #1.param, fonteTitre$
        print #1.avanti, fonteTitre$
        print #1.titreGen, fonteTitre$
 
        'données pré-réglées
        print #1.freq1, freq1
        print #1.vol1, vol1
        print #1.freq2, freq2
        print #1.vol2, vol2
 
        print #1.comboEch,"selectindex ";indexFech
        fEchant=val(FreqEch$(indexFech))
 
        print #1.comboRes,"selectindex ";indexRes
        resolution=val(WaveRes$(indexRes))
 
        print #1.comboVoi,"selectindex ";indexVoies
        voies=val(WaveNbvoies$(indexVoies))
 
        print #1.bxDureeWav, duree
        print #1.annulCalc, "!disable"
        print #1.freq1, "!setfocus"
        print #1, "trapclose [quitter]"
 
    wait
 
end
'***************sous-programmes********************

[quitter]
    'quitte le programme
    close #1
    end
 
[annule_calcul]
    'pas encore créé

    'on annule la création en cours (temps trop long, ou erreur de saisie
    'et vouloir relancer avant la fin réelle du traitement, ...)
    wait
 
[changeDestination]
    print "[changeDestination]"
    filedialog "Save to, entrer un nom pour le fichier :","*.wav",chemin$
    if chemin$<>"" then
        numCar=0
        antislash=0
 
        while antislash=0
            a$=mid$(chemin$,len(chemin$)-numCar,1)
            if a$="\" or numCar>len(chemin$) then antislash=1
            numCar=numCar+1
        wend
 
        NomWav$=right$(chemin$,numCar-1)
        CheminWav$=left$(chemin$,len(chemin$)-numCar+1)
 
        print #1.cheminWav, CheminWav$
        print #1.nomWav, NomWav$
 
    end if
    wait
 
 
[chercher_periode_somme]
    print "[chercher_periode_somme]"
    tour=0
    t=0
    gen1zm=0
    gen2zm=0
    trouve=0
    limitetemps=10*fEchant  '(10 fois la fréquence d'échantillonnage, soit 10 secondes)

    while trouve=0
 
        anciengen1=gen1
        anciengen2=gen2
 
        gen1=vol1*sin(omega1*t)
        gen2=vol2*sin(omega2*t)
 
        print gen1;"       ";gen2
 
        'détecte le passage par zéro en montant
        if anciengen1<0 and gen1>=0 then gen1zm=1:print "generateur1 passe 0 en montant"
        if anciengen2<0 and gen2>=0 then gen2zm=1:print "generateur2 passe 0 en montant"
 
        if gen1zm=1 and gen2zm=1 then
            trouve=1
            tours=tour-1 '  (on retire 1 parce que on vient de trouver le premier
            '               point de la période suivante)
            print "*** trouvé au ";tour;"ème calcul ! ***"
        end if
 
        gen1zm=0
        gen2zm=0
 
        tour=tour+1
        t=t+tEchant
        if t>limitetemps then trouve=1:tempsdepasse=1:tours=tour:print "!!! pas trouvé !!!"
 
    wend
 
    if tempsdepasse then
        repetitions=1
    else
        repetitions=int(duree/(tours*tEchant)+1)
    end if
    print "il y aura ";repetitions;" fois la période de la somme"
    '(période finale = période décrivant totalement la forme d'onde de la somme)
    'on arrondi à l'entier supérieur, et on obtient le nombre de fois qu'il faudra
    'répéter la période finale pour aboutir à la durée souhaitée
return
 
 
[f_echantillonnage]
    print "[f_echantillonnage]"
 
    'lecture valeur combobox
    print #1.comboEch,"selectionindex? indexFech"
    fEchant=val(FreqEch$(indexFech))
 
    wait
 
 
[genere_wav]
    print "[genere_wav]"
    'récupération fréquences et volumes des générateurs
    print #1.freq1, "!contents? a$":freq1=val(a$)
    print #1.vol1, "!contents? a$":vol1=val(a$)
    print #1.freq2, "!contents? a$":freq2=val(a$)
    print #1.vol2, "!contents? a$":vol2=val(a$)
 
    'calcul pulsations
    omega1=2*pi*freq1
    omega2=2*pi*freq2
 
    'récupération paramètres wav
    print #1.bxDureeWav, "!contents? a$":duree=val(a$)
 
    'déterminer la période décrivant complètement la somme des deux fréquences
    tEchant=1/fEchant
    gosub [chercher_periode_somme]
 
    'en fonction de la résolution et du nombre de voies on détermine le codage
    'pour la durée d'une "période somme"
    amplitudemax=400
    t=0
    if resolution=8 then
        if voies=1 then gosub [fichier_8bits_mono]
        if voies=2 then gosub [fichier_8bits_stereo]
    end if
 
    if resolution=16 then
        if voies=1 then gosub [fichier_16bits_mono]
        if voies=2 then gosub [fichier_16bits_stereo]
    end if
 
    'on prépare les données pour la durée finale souhaitée
    for a=1 to repetitions
        audio$=audio$+periodesomme$
        'audio$=audio$+left$(periodesomme$,len(periodesomme$)-1)
    next
 
    'On prépare l'en-tête du fichier
    longueurAudio=len(audio$)
    nbOctet=resolution/8    'nombre d'octets par échantillon pour une voie
    fluxDonnees=nbOctet*voies*fEchant'débit en nombre d'octets par seconde

    'données du programme
    et$="RIFF"                              'toujours RIFF
    et$=et$+littleEndian$(36+longueurAudio,4)'taille fichier (devrait être 44+nbre d'octets audio ???)
    et$=et$+"WAVE"                          'toujours WAVE
    et$=et$+"fmt "                          'toujours "fmt "
    et$=et$+littleEndian$(16,4)              '16, 18 ou 40
    et$=et$+littleEndian$(1,2)               '1=PCM, Pulse Code Modulation, classique pour un wave ordinaire
    et$=et$+littleEndian$(voies,2)           'nombre de canaux interlacés (1=mono, 2=stéréo,...)
    et$=et$+littleEndian$(fEchant,4)         'fréquence échantillonnage
    et$=et$+littleEndian$(fluxDonnees,4)     'nombre moyen d'octets par seconde
    et$=et$+littleEndian$(nbOctet,2)         'taille du bloc de donnees
    et$=et$+littleEndian$(resolution,2)      'bits par échantillon (pour une voie)
    et$=et$+"data"                          'toujours "data", annonce les données audio
    et$=et$+littleEndian$(longueurAudio,4)   'longueur en octets des données audio

    'le futur fichier audio est complètement contenu dans la chaine wav$
     wav$=et$+audio$
 
    'on transfère wav$ dans le fichier
    Fichier$=CheminWav$+"\"+NomWav$ '
    dim info$(10, 10)
    files CheminWav$, NomWav$, info$()
 
    if val(info$(0, 0))<>0 then 'le fichier existe, le supprimer
        print "kill Fichier$ : ";Fichier$
        kill Fichier$
    end if
 
    print Fichier$
    open Fichier$ for output as #audio
        print #audio,wav$
    close #audio
 
    'contrôle (prévoir un arrêt prématuré
    playwave Fichier$
 
    wait 'return provisoire 'ce serait-y pas un wait, des fois ?

 
[fichier_8bits_mono]
    print "[fichier_8bits_mono]"
 
    maxoct=0:minoct=256 '(c'est inversé, c'est normal ici)

    for a=0 to tours
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(128+somme*256/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        periodesomme$=periodesomme$+chr$(echantillon)
 
        'if valeurmaxoctet<echantillon then valeurmaxoctet=echantillon
        'if valeurminoctet>echantillon then valeurminoctet=echantillon
        print "somme = ";somme;", échantillon = ";echantillon
 
        'prépare pour échantillon suivant
        t=t+tEchant
    next
    periodesomme$=left$(periodesomme$,len(periodesomme$)-1)
    return
 
 
[fichier_8bits_stereo]
    print "[fichier_8bits_stereo]"
 
    for a=0 to tours
 
        'voie gauche
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(128+somme*256/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        periodesomme$=periodesomme$+chr$(echantillon)
 
 
        'voie droite
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(128+somme*256/amplitudemax)   'échantillons
        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        periodesomme$=periodesomme$+chr$(echantillon)
 
        t=t+tEchant
    next
    periodesomme$=left$(periodesomme$,len(periodesomme$)-1)
return
 
 
[fichier_16bits_mono]
    print "[fichier_16bits_mono]"
    for a=0 to tours
 
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(somme*65536/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        octetFort=int(echantillon/256)
        octetFaible=int(echantillon)-octetFort*256
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        t=t+tEchant
    next
 
return
 
 
[fichier_16bits_stereo]
        print "[fichier_16bits_mono]"
    for a=0 to tours
 
        'voie gauche
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(somme*65536/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        octetFort=int(echantillon/256)
        octetFaible=int(echantillon)-octetFort*256
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        'voie droite
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(somme*65536/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
        octetFort=int(echantillon/256)
        octetFaible=int(echantillon)-octetFort*256
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        t=t+tEchant
    next
 
    return
 
[Wav_nombre_voies]
    print "[Wav_nombre_voies]"
    print #1.comboVoi,"selectionindex? indexVoies"
    voies=val(WaveNbvoies$(indexVoies))
 
    wait
 
[Wav_resolution]
    print "[Wav_resolution]"
    print #1.comboRes,"selectionindex? indexRes"
    resolution=val(WaveRes$(indexRes))
 
    wait
 
'************** fonctions ***************

function littleEndian$(nombre,longueur)
    print
    print "function littleEndian$ ";
    print "nombre=";nombre;"  longueur=";longueur
    code$="":reste=nombre
 
    for a=longueur-1 to 1 step -1
 
        octet=int(nombre/256^a)
        code$=chr$(octet)+code$
 
        reste=nombre-octet*256^a
 
        nombre=reste
 
        print "boucle=";a;" octet=";octet;"  nombre=";nombre;"  code$=";code$
    next
 
    code$=chr$(reste)+code$
    littleEndian$=code$
 
    'vérification
    for a=1 to longueur
        print asc(mid$(code$,a,1));" ";
    next
    print
end function
 
 
 
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 06/03/2016 à 15h14

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Citation:
qu'avec des entiers

Et ben y a qu'à arrondir la période.
Mais sinon....Waouu! Superbe!
Je vais regarder si je vois où est le problème
Comme il y a deux sons, il y a forcément un re passage quelque part
Ou une coupure de procédure qui est prise pour un redémarrage plus addition.
Y a un os dans l'pâté.
____________________
Roro

   
Le 06/03/2016 à 15h41

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Quand on change la fréquence (par le textbox) on relance le processus
Puisqu'il y a changement de donnée d'entrée
Soit il faut initialiser (effacer) les dernières données
Soit il faut faire un saut quelque part.
J'y retourne...
____________________
Roro

   
Le 06/03/2016 à 17h47

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Pour pouvoir changer les "freq" et les "vol", j'ai ajouté un bouton "Changer" qui branche à un [init] 10 lignes avant le wait.
il n'y a plus qu'un seul son et la freq est bien modifiée
____________________
Roro

   
Le 07/03/2016 à 09h01

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
J'ai résolu le problème de la durée qui s'accroissait : je n'avais pas vidé les chaines periodesomme$ et audio$, donc forcément, même en effaçant le fichier, on y remettaiit tout ce qui était généré depuis le début...

Mais il y a autre chose qui va dans le sens de tes observations, et la forme d'onde n'est pas toujours très propre. Je vais vérifier l'intégralité du programme.
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 07/03/2016 à 09h16

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Citation:
je n'avais pas vidé les chaines periodesomme$

Passe moi tes dernières modifs
____________________
Roro

   
Le 07/03/2016 à 13h10

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
ajouté les 3ème et 4ème lignes

Code VB :
 
    'en fonction de la résolution et du nombre de voies on détermine le codage
    'pour la durée d'une "période somme"
    periodesomme$=""    'la chaine qui contiendra les échantillons de la période
    audio$=""           'la chaine qui contiendra les échantillons des périodes avant transfert en fichier
    
    amplitudemax=400
    t=0
 
    if resolution=8 then
        if voies=1 then gosub [fichier_8bits_mono]
        if voies=2 then gosub [fichier_8bits_stereo]
    end if
 
    if resolution=16 then
        if voies=1 then gosub [fichier_16bits_mono]
        if voies=2 then gosub [fichier_16bits_stereo]
    end if
 
    'on prépare les données pour la durée finale souhaitée
    for a=1 to repetitions
        audio$=audio$+periodesomme$
        'audio$=audio$+left$(periodesomme$,len(periodesomme$)-1)
    next
 
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 07/03/2016 à 16h34

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Code VB :
[chercher_periode_somme] 


Je suis arrivé à calculer la durée de la periode_somme en partant des deux fréquences et de leur pgcd, mais ça va faire des lignes et des lignes de code, et on a plus vite fait de programmer une boucle qui détecte le passage simultané par zéro en montant, de deux courbes sinusoidales...
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 09/03/2016 à 13h25

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Citation:
on annule la création en cours (temps trop long

ça ne suffit pas en vidant la chaine avec un: audio$="" placé au bon endroit ?
____________________
Roro

   
Le 10/03/2016 à 20h21

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Normalement oui. Mais j'ai perdu mon .bas et je ne peux pas répondre pour le moment, le fichier doit être quelque part entre le système Linux et le windows virtuel, j'ai juste la version d'avant.

Pas de panique, il n'est pas effacé, il est seulement là où je ne vois pas pourquoi je l'y aurait mis ;)
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 11/03/2016 à 11h36

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Citation:
j'ai perdu mon .bas

Bah tu aura tout simplement oublié de l'enregistrer ou tu l'aura supprimé.
Il n'y a pas de "no men's land" entre la VM et l'OS résident.
Tu nous fais vraiment chier avec ton Linux; paye toi un pc d'occase
Linux, je m'y suis pris la tête des heures et des jour; j'en ai testé trente six distrib's
Tant que ça sera la merde pour installer "à la main" et tant qu'il n'y aura pas une description complète du fonctionnement du système claire et accessible à un cerveau normal; Linux restera dans les limbes.
ça fait trente ans que la souris existe, il faut être maso (ou intégriste) pour se taper de la ligne de commande
Avec les inévitables fautes de frappe et le bordel intense qu'elles peuvent mettre.
Et pourtant, crois moi qu'en tant qu'anarchiste affirmé, je suis moi aussi pour le "libre"
____________________
Roro

   
Le 11/03/2016 à 15h35

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
o-hé-lui-hein-maizalors-l'autre ! faudrait peut-être pas étendre ton expérience malheureuse au cas général, non plus^^

Cycliste ! ;)

Et d'abord XP n'a jamais tourné aussi vite que sous Linux, nan mais !

Et je l'ai toujours, mon petit ordi sous xp, mais je ne m'en sers pas tous les jours, c'est pour quand je suis de sortie. Son malaise n'était pas un malware, mais windows qui s'est mis à lire le disque en mode PIO plutôt qu'ultraDMA, j'ai appris que c'est un comportement connu de la part de XP, lorsqu'il se produit des erreurs disque.

Par ailleurs je m'attendais à ce que tout soit soudé, là dedans, mais j'ai vu qu'on pouvait tout à fait changer mémoire et disque dur, comme sur un grand, c'est bon à savoir.

Pour revenir au sujet, il est nécessaire de vider periodesomme$ en même temps que audio$. periodesomme$ contient les échantillons de la période, si on ne la vide pas lors d'un nouveau calcul suite au clic sur "générer", elle comprendra la période générée précédemment plus la période actuelle. Comme elle n'était remise à zéro nulle part, je te laisse deviner le résultat...

Pour bien faire, il faudrait faire periodesomme$="" au début de chacun des sous-programmes [fichier_8bits...] et [fichier_16bits...], mais j'ai trouvé plus commode de le faire en une seule fois juste avant les conditions qui aiguillent sur ces sous-programmes, c'est moins intuitif, cependant. Ça semble fonctionner, tant en durée du fichier wav qu'en qualité audio.

Reste maintenant à vérifier les autres sous-programmes, car je n'ai vraiment travaillé que sur le _8bits_mono, et les autres ne fonctionnaient pas.
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 11/03/2016 à 15h39

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Roland:

Christophe:
on annule la création en cours (temps trop long


ça ne suffit pas en vidant la chaine avec un: audio$="" placé au bon endroit ?


Ce traitement n'est pas encore d'actualité, je ne saurais répondre...
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 11/03/2016 à 21h38

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
J'ai ajouté: periodesomme$="" à [init], ça marche nickel
Mais le bouton "Changer" devrait plutôt être "Vider"
____________________
Roro

   
Le 13/03/2016 à 11h17

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Tu as créé un [init] ?

Pour ma part j'ai encore des choses à apprendre, je suppose...

De mon côté aussi, la génération en 8 bits mono fonctionne maintenant, mais vise(z) un peu ces deux captures d'écran :






Réglages pour les deux essais :
mono 8bits
fréquence d'échantillonnage 11025 Hz

Dubitatif je suis, et l'écoute corrobore le visuel, il y a autre chose que le théorème de Shannon dans la vie numérique...

Je me conseille la lecture de ceci avant d'aller plus avant.

Détail supplémentaire : dans les deux cas le graphe doit aller du bord gauche au bord droit de sa fenêtre. Dans le premier il dépasse, dans le second il s'arrête avant. petit détail à revoir aussi

Bon dimanche
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 13/03/2016 à 14h11

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
hey..;Poste ton dernier code
On est largués là
Non, il ne s'agit pas d'un fichier init, mais d'un simple branchement (décrit précédemment).
____________________
Roro

   
Le 13/03/2016 à 15h34

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Les choses s'arrangent lorsque je met l'échantillonnage à 44100 Hz, mais c'est pas encore ça...

Alors j'ai voulu jouer avec la résolution, et je refais les sous-programmes 16 bits, car dans le fichier ce seront des entiers signés (-32768 à +32768) qui sont attendus alors que j'ai prévu 0 à 65535. En pleins travaux, donc, mais tant qu'on choisit pas 16bits, y'a pas de souci.

Voici le prog tel qu'il est :

Code VB :
 
 
'Géné BF 2 fréquences
'ajout affichage forme d'onde : en cours

'pour le moment, seule la génération 8bits fonctionne, mal dans les hautes fréquences

'reste à faire : barre de progression (_2.bas)
'                générateur morse (_3.bas) 'clin d'oeil à pmp^^

 
    'nomainwin

    NomWav$="pardefaut.wav"
    CheminWav$=DefaultDir$
 
    'dimensions de la fenêtre
    WindowWidth = 615
    WindowHeight = 495
 
    'formats d'affichage
    fonteGlobale$="font ms_sans_serif 0 16"
    fonteTitre$="!font ms_sans_serif 0 16 bold"
 
    'valeurs par défaut
    pi=3.1415926536
    freq1=880
    vol1=70
    freq2=440
    vol2=70
 
    duree=1
 
    'fréquences échantillonnage, Hz
    indexFech=1 'élément qui sera affiché dans la combobox
    FreqEch$(1)="11025"
    FreqEch$(2)="22050"
    FreqEch$(3)="44100"
 
    'résolution échantillonnage, bits
    indexRes=1
    WaveRes$(1)="8"
    WaveRes$(2)="16"
 
    'nombre de voies
    indexVoies=1
    WaveNbvoies$(1)="1-Mono"
    WaveNbvoies$(2)="2-Stereo"
 
    'création de l'interface utilisateur
    statictext #1.titreGen, "Générateurs :", 15, 15, 100, 20
 
    statictext #1.frequences, "Fréquence, Hz", 85, 40, 100, 20
    statictext #1.volumes, "Volume, 0 à 100", 195, 40, 100, 20
 
    statictext #1.gen1, "Gen. 1", 30, 65, 40, 20
    textbox #1.freq1, 80, 60, 100, 25
    textbox #1.vol1, 190, 60, 100, 25
 
    statictext #1.gen2, "Gen. 2", 30, 95, 40, 20
    textbox #1.freq2, 80, 90, 100, 25
    textbox #1.vol2, 190, 90, 100, 25
 
    button #1.genWav, "Générer", [genere_wav], UL, 300, 60, 80, 55
 
    largeurvisu=200
    hauteurvisu=120
    graphicbox #1.visu, 390, 20, largeurvisu, hauteurvisu
 
    statictext #1.sortie, "Fichier de sortie :", 15, 140, 125, 20
    statictext #1.nomWav, NomWav$, 140, 140, 390, 20
    button #1.changeDest, "Emplacement et nom du fichier", [changeDestination], UL, 30, 165, 350, 25
    statictext #1.cheminWav, CheminWav$, 30, 195, 300, 40
 
    statictext #1.param, "Paramètres du fichier Wave :", 15, 245, 200, 20
 
    statictext #1.fech, "Freq. échantillonnage, Hz", 30, 270, 170, 20
    combobox #1.comboEch, FreqEch$(), [f_echantillonnage], 210, 268, 75, 20
 
    statictext #1.fech, "Résolution, bits", 30, 300, 170, 20
    combobox #1.comboRes, WaveRes$(), [Wav_resolution], 210, 297, 75, 20
 
    statictext #1.fech, "Nombre de voies", 30, 330, 170, 20
    combobox #1.comboVoi, WaveNbvoies$(), [Wav_nombre_voies], 210, 328, 75, 20
 
    statictext #1.dureeWav, "Durée, s", 30, 360, 170, 20
    textbox #1.bxDureeWav, 210, 358, 75, 25
    'button #1.okDuree, "OK", [valide_duree], UL, 290, 360, 25, 25

    statictext #1.avanti, "En avant !", 15, 400, 270, 20
 
    button #1.annulCalc, "Annuler", [annule_calcul], UL, 120, 425, 80, 25
    button #1.quit, "Quitter", [quitter], UL, 300, 425, 80, 25
 
    'ouverture fenêtre d'interface utilisateur
    open "Géné. BF" for window as #1
 
        'fonte global
        print #1, fonteGlobale$
 
        'fonte titres
        print #1.titreGen, fonteTitre$
        print #1.sortie, fonteTitre$
        print #1.param, fonteTitre$
        print #1.avanti, fonteTitre$
        print #1.titreGen, fonteTitre$
 
        'données pré-réglées
        print #1.freq1, freq1
        print #1.vol1, vol1
        print #1.freq2, freq2
        print #1.vol2, vol2
 
        print #1.visu, "down"
        print #1.visu, "fill darkgray"
        print #1.visu, "color lightgray"
        print #1.visu, "line 0 ";hauteurvisu/2;" ";largeurvisu;" ";hauteurvisu/2
        print #1.visu, "UP"
 
        print #1.comboEch,"selectindex ";indexFech
        fEchant=val(FreqEch$(indexFech))
 
        print #1.comboRes,"selectindex ";indexRes
        resolution=val(WaveRes$(indexRes))
 
        print #1.comboVoi,"selectindex ";indexVoies
        voies=val(WaveNbvoies$(indexVoies))
 
        print #1.bxDureeWav, duree
        print #1.annulCalc, "!disable"
        'peut-être une bonne idée de lancer d'ici une visu avec les paramètres
        'actuels
        print #1.freq1, "!setfocus"
        print #1, "trapclose [quitter]"
 
    wait
 
end
'***************sous-programmes********************

[quitter]
    'quitte le programme
    close #1
    end
 
[annule_calcul]
    'pas encore créé

    'on annule la création en cours (temps trop long, ou erreur de saisie
    'et vouloir relancer avant la fin réelle du traitement, ...)
    wait
 
[changeDestination]
    print "[changeDestination]"
    filedialog "Save to, entrer un nom pour le fichier :","*.wav",chemin$
    if chemin$<>"" then
        numCar=0
        antislash=0
 
        while antislash=0
            a$=mid$(chemin$,len(chemin$)-numCar,1)
            if a$="\" or numCar>len(chemin$) then antislash=1
            numCar=numCar+1
        wend
 
        NomWav$=right$(chemin$,numCar-1)
        CheminWav$=left$(chemin$,len(chemin$)-numCar+1)
 
        print #1.cheminWav, CheminWav$
        print #1.nomWav, NomWav$
 
    end if
    wait
 
 
[chercher_periode_somme]
    print "[chercher_periode_somme]"
 
 
    tour=0
    t=0
    gen1zm=0
    gen2zm=0
    trouve=0
    limitetemps=10*fEchant  '(10 fois la fréquence d'échantillonnage, soit 10 secondes)
    '(y'a pas un bug dans limitetemps ?)

    visu$=""
 
    while trouve=0
'2 calculs :
'           courbe réelle, pour la prise en compte des volumes et l'affichage
'           courbe sans volume, pour détecter la fin de la période

        'recherche durée période
        anciengen1r=gen1r
        anciengen2r=gen2r
        gen1r=sin(omega1*t)
        gen2r=sin(omega2*t)
 
        print gen1r;"       ";gen2r
 
        'courbe pour affichage
        gen1aff=vol1*sin(omega1*t)
        gen2aff=vol2*sin(omega2*t)
 
        'calcul échantillon
        sommeaff=gen1aff+gen2aff
        echantillon=int(128+sommeaff*256/800)
 
        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        visu$=visu$+chr$(echantillon)
        print "visu$=visu$+";echantillon-128
 
 
        'détecte le passage par zéro en montant
        if anciengen1r<0 and gen1r>=0 then gen1zm=1:print "generateur1 passe 0 en montant"
        if anciengen2r<0 and gen2r>=0 then gen2zm=1:print "generateur2 passe 0 en montant"
 
        if gen1zm=1 and gen2zm=1 then
            trouve=1
            tours=tour-1 '  (on retire 1 parce que on vient de trouver le premier
            '               point de la période suivante)
            print "*** trouvé au ";tour;"ème calcul ! ***"
        end if
 
        gen1zm=0
        gen2zm=0
 
        tour=tour+1
        t=t+tEchant
        if t>limitetemps then trouve=1:tempsdepasse=1:tours=tour:print "!!! pas trouvé !!!"
 
    wend
 
    visu$=left$(visu$,len(visu$)-1)
    gosub [visu]
 
    if tempsdepasse then
        repetitions=1
    else
        repetitions=int(duree/(tours*tEchant)+1)
    end if
    print "il y aura ";repetitions;" fois la période de la somme"
    '(période finale = période décrivant totalement la forme d'onde de la somme)
    'on arrondi à l'entier supérieur, et on obtient le nombre de fois qu'il faudra
    'répéter la période finale pour aboutir à la durée souhaitée
return
 
 
[f_echantillonnage]
    print "[f_echantillonnage]"
 
    'lecture valeur combobox
    print #1.comboEch,"selectionindex? indexFech"
    fEchant=val(FreqEch$(indexFech))
 
    wait
 
 
[genere_wav]
    print "[genere_wav]"
    audio$="" 'la chaine qui contiendra les données audio
    'récupération fréquences et volumes des générateurs
    print #1.freq1, "!contents? a$":freq1=val(a$)
    print #1.vol1, "!contents? a$":vol1=val(a$)
    print #1.freq2, "!contents? a$":freq2=val(a$)
    print #1.vol2, "!contents? a$":vol2=val(a$)
 
    'calcul pulsations
    omega1=2*pi*freq1
    omega2=2*pi*freq2
 
    'récupération paramètres wav
    print #1.bxDureeWav, "!contents? a$":duree=val(a$)
 
    'déterminer la période décrivant complètement la somme des deux fréquences
    tEchant=1/fEchant
    gosub [chercher_periode_somme]
 
    'en fonction de la résolution et du nombre de voies on détermine le codage
    'pour la durée d'une "période somme"
    periodesomme$=""    'la chaine qui contiendra les échantillons de la période
    audio$=""           'la chaine qui contiendra les périodes avant transfert sur disque
    amplitudemax=400
    t=0
    if resolution=8 then
        if voies=1 then gosub [fichier_8bits_mono]
        if voies=2 then gosub [fichier_8bits_stereo]
    end if
 
    if resolution=16 then
        if voies=1 then gosub [fichier_16bits_mono]
        if voies=2 then gosub [fichier_16bits_stereo]
    end if
 
    'on prépare les données pour la durée finale souhaitée
    for a=1 to repetitions
        audio$=audio$+periodesomme$
        'audio$=audio$+left$(periodesomme$,len(periodesomme$)-1)
    next
 
    'On prépare l'en-tête du fichier
    longueurAudio=len(audio$)
    nbOctet=resolution/8    'nombre d'octets par échantillon pour une voie
    fluxDonnees=nbOctet*voies*fEchant'débit en nombre d'octets par seconde

    'données du programme
    et$="RIFF"                              'toujours RIFF
    et$=et$+littleEndian$(36+longueurAudio,4)'taille fichier (devrait être 44+nbre d'octets audio ???)
    et$=et$+"WAVE"                          'toujours WAVE
    et$=et$+"fmt "                          'toujours "fmt "
    et$=et$+littleEndian$(16,4)              '16, 18 ou 40
    et$=et$+littleEndian$(1,2)               '1=PCM, Pulse Code Modulation, classique pour un wave ordinaire
    et$=et$+littleEndian$(voies,2)           'nombre de canaux interlacés (1=mono, 2=stéréo,...)
    et$=et$+littleEndian$(fEchant,4)         'fréquence échantillonnage
    et$=et$+littleEndian$(fluxDonnees,4)     'nombre moyen d'octets par seconde
    et$=et$+littleEndian$(nbOctet,2)         'taille du bloc de donnees
    et$=et$+littleEndian$(resolution,2)      'bits par échantillon (pour une voie)
    et$=et$+"data"                          'toujours "data", annonce les données audio
    et$=et$+littleEndian$(longueurAudio,4)   'longueur en octets des données audio

    'le futur fichier audio est complètement contenu dans la chaine wav$
     wav$=et$+audio$
 
    'on transfère wav$ dans le fichier
    Fichier$=CheminWav$+"\"+NomWav$ '
    dim info$(10, 10)
    files CheminWav$, NomWav$, info$()
 
    if val(info$(0, 0))<>0 then 'le fichier existe, le supprimer
        print "kill Fichier$ : ";Fichier$
        kill Fichier$
    end if
 
    print Fichier$
    open Fichier$ for output as #audio
        print #audio,wav$
    close #audio
 
    'contrôle (prévoir un arrêt prématuré
    playwave Fichier$
 
    wait 'return provisoire 'ce serait-y pas un wait, des fois ?

 
[fichier_8bits_mono]
    print "[fichier_8bits_mono]"
 
    maxoct=0:minoct=256 '(c'est inversé, c'est normal ici)

    for a=0 to tours-1
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(128+somme*256/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        periodesomme$=periodesomme$+chr$(echantillon)
        print "somme = ";somme;", échantillon = ";echantillon
 
        'prépare pour échantillon suivant
        t=t+tEchant
    next
 
    return
 
 
[fichier_8bits_stereo]
    print "[fichier_8bits_stereo]"
 
    for a=0 to tours-1
 
        'voie gauche
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(128+somme*256/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        periodesomme$=periodesomme$+chr$(echantillon)
 
 
        'voie droite
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(128+somme*256/amplitudemax)   'échantillons
        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine
        periodesomme$=periodesomme$+chr$(echantillon)
 
        t=t+tEchant
    next
 
return
 
 
[fichier_16bits_mono]
    print "[fichier_16bits_mono]"
 
    'il y a une histoire d'entier signé ?
    'on va placer le bit de signe sur l'octet de poids fort, bit de poids fort
    'les valeurs ne vont plus de 0 à 65536 mais de -32768 à +32767
    '
    for a=0 to tours-1
 
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(somme*32768/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        print:print "échantillon = ";echantillon
        'octetFort=abs(int(echantillon/256))
        'print "octet fort =";octetFort

        if echantillon<0 then
            print "échantillon négatif "
            octetFort=abs(int(echantillon/128))+128   'signe négatif
            print "octet fort = ";octetFort
            octetFaible=abs(int(echantillon)-octetFort*256)
            print "octetFaible = ";octetFaible
        else
            print "échantillon positif"
            octetFort=abs(int(echantillon/256))
            print "octet fort = ";octetFort
            octetFaible=abs(int(echantillon)-octetFort*256)
            print "octetFaible = ";octetFaible
        end if
 
        'octetFaible=abs(int(echantillon)-octetFort*256)
        'print "octetFaible = ";octetFaible
        'periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)

        t=t+tEchant
    next
 
return
 
 
[fichier_16bits_stereo]
        print "[fichier_16bits_mono]"
    for a=0 to tours
 
        'voie gauche
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(somme*65536/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        octetFort=int(echantillon/256)
        octetFaible=int(echantillon)-octetFort*256
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        'voie droite
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
        echantillon=int(somme*65536/amplitudemax)   'échantillons

        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
        octetFort=int(echantillon/256)
        octetFaible=int(echantillon)-octetFort*256
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        t=t+tEchant
    next
 
    return
 
[visu]
    print "[visu]"
 
    print #1.visu, "down"        '
    print #1.visu, "cls"
    print #1.visu, "fill darkgray"
 
    pas=largeurvisu/len(visu$)
    x=0
    y=hauteurvisu/2
 
    print #1.visu, "color cyan"
    print #1.visu, "down"
    'print "ahem goto ";x;" ";y - asc(mid$(visu$,1,1)) - 128
    'print #1.visu, "goto ";x;" ";y - asc(mid$(visu$,1,1)) - 128

 
 
    for a=1 to len(visu$)
        ech=asc(mid$(visu$,a,1)) - 128
        'print "visu, élément ";a;"  : ";ech;" affiché en ";y-ech

 
        print #1.visu, "goto ";x;" ";y - ech
        print "bhem goto ";x;" ";y - ech
 
         x=x+pas
    next
 
    print #1.visu, "color lightgray"
    print #1.visu, "line 0 ";y;" ";largeurvisu;" ";y
    print #1.visu, "up"
 
 
    print #1.visu, "up"
    return
 
 
[Wav_nombre_voies]
    print "[Wav_nombre_voies]"
    print #1.comboVoi,"selectionindex? indexVoies"
    voies=val(WaveNbvoies$(indexVoies))
 
    wait
 
[Wav_resolution]
    print "[Wav_resolution]"
    print #1.comboRes,"selectionindex? indexRes"
    resolution=val(WaveRes$(indexRes))
 
    wait
 
'************** fonctions ***************

function littleEndian$(nombre,longueur)
    print
    print "function littleEndian$ ";
    print "nombre=";nombre;"  longueur=";longueur
    code$="":reste=nombre
 
    for a=longueur-1 to 1 step -1
 
        octet=int(nombre/256^a)
        code$=chr$(octet)+code$
 
        reste=nombre-octet*256^a
 
        nombre=reste
 
        print "boucle=";a;" octet=";octet;"  nombre=";nombre;"  code$=";code$
    next
 
    code$=chr$(reste)+code$
    littleEndian$=code$
 
    'vérification
    for a=1 to longueur
        print asc(mid$(code$,a,1));" ";
    next
    print
end function
 
 
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 13/03/2016 à 16h08

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2083
Et ben mazette! C'est pas simple.
____________________
Roro

   
Le 13/03/2016 à 23h48

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
J'admet que c'est pas très clair (pmp : prends-en de la graine ;) ) Le sous-programme de recherche de la période-somme clarifié

Code VB :
 
[chercher_periode_somme]
    print "[chercher_periode_somme]"
    'on fait la somme à l'instant t des périodes des générateurs
    'on débute quend les signaux sont tous les deux à zéro et vont vers des valeurs positives
    'on termine quand on retrouve les mêmes conditions
    'on a alors fait le tour de toutes les valeurs prises par la somme au fil du temps
    'et on a obtenu une période reproductible à volonté

    tour=0      'numéro d'ordre de l'échantillon actuellement traité

    t=0         'somme des périodes d'échantillonnage passées depuis le début de la recherche

    gen1zm=0    'passe à 1 quand le signal du générateur 1 passe par zéro en montant
    gen2zm=0    'idem pour le gen2

    trouve=0    'à 1 quand on a trouvé la période somme
    limitetemps=10*fEchant  'limite de temps pour éviter une recherche à l'infini
'(y'a pas un bug dans limitetemps ?)

 
    visu$=""
    while trouve=0
 
    'recherche durée de la période multiple des périodes des générateurs
        anciengen1r=gen1r
        anciengen2r=gen2r
        gen1r=sin(omega1*t)
        gen2r=sin(omega2*t)
 
        print gen1r;"       ";gen2r
 
    'courbe pour affichage sur fenêtre
        gen1aff=vol1*sin(omega1*t)
        gen2aff=vol2*sin(omega2*t)
 
        'calcul échantillon, exprimé sur un octet, pour stockage en chaine
        sommeaff=gen1aff+gen2aff
        echantillon=int(128+sommeaff*256/800)
 
        'arrondir
        entiere=int(echantillon)
        decimale=somme-int(echantillon)
        if decimales>=0.5 then echantillon=entiere+1 else echantillon=entiere
 
        'stoker l'échantillon en chaine pour affichage de la période
        visu$=visu$+chr$(echantillon)
        print "visu$=visu$+";echantillon-128
 
 
    'détecte le passage par zéro en montant : on a trouvé la fin de la période multiple
        if anciengen1r<0 and gen1r>=0 then gen1zm=1:print "generateur1 passe 0 en montant"
        if anciengen2r<0 and gen2r>=0 then gen2zm=1:print "generateur2 passe 0 en montant"
 
        if gen1zm=1 and gen2zm=1 then
            trouve=1
            tours=tour-1 '  (on retire 1 parce que on vient de trouver le premier
            '               point de la période suivante)
            print "*** trouvé au ";tour;"ème calcul ! ***"
        end if
 
        gen1zm=0
        gen2zm=0
 
        tour=tour+1
        t=t+tEchant
        if t>limitetemps then trouve=1:tempsdepasse=1:tours=tour:print "!!! pas trouvé !!!"
 
    wend
 
 
    visu$=left$(visu$,len(visu$)-1)
    gosub [visu]
 
    if tempsdepasse then
        repetitions=1
    else
        repetitions=int(duree/(tours*tEchant)+1)
    end if
    print "il y aura ";repetitions;" fois la période de la somme"
 
return
 
 

Autrement, te prend pas plus le choux que ça, le programme passe bien par là ou il doit passer.

Les deux difficultés actuelles consistent à trouver une période multiple des deux fréquences désirées ET de la fréquence d'échantillonnage pour éviter de finir la période sur une valeur qui n'est pas zéro, et à enregistrer en fichier un entier signé codé sur deux octets en little endian (qui n'est pas sioux^^).

Dans les deux cas je m'en sors sur tableur, donc y'a pas de souci, c'est juste la conversion en basic qui demande de la réflexion.

Peut-être aussi que le théorème de Nyquist-Shannon est essentiel mais pas suffisant pour garantir la cohérence des résultats obtenus, et que je suis tombé dans le panneau. J'ai parcouru la doc citée dans mon dernier post, il me semble avoir lu quelque chose allant dans ce sens, mais le niveau technique du topo est plutot ardu pour mes connaissances.

Mais on avance...



Edité par Christophe Le 14/03/2016 à 11h11
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 14/03/2016 à 11h09

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
J'ai repris les données du problème...

intervalle entre deux échantillons : 1/F échantillonnage = 1/11025 = 90.703 µs

F1=440
F2=330

pgcd de 440 et 330 : 110

F1. 440/pgcd = 440/110 = 4
F2. 330/pgcd = 330/110 = 3

F1. 4 périodes = 4*1/440 = 9.0909 ms
F2. 3 périodes = 3*1/330 = 9.0909 ms

Nombre d'échantillons durant 9.0909 ms :
T ech = 90.703 µs = 0.090703 ms
n = 9.0909/0.090703 = 100 'celle qui sonne bien


Meme calcul pour :

F1=4400
F2=3300

pgcd de 4400 et 3300 : 1100

F1. 4400/pgcd = 4400/1100 = 4
F2. 3300/pgcd = 3300/1100 = 3

F1. 4 périodes = 4*1/4400 = 0.90909 ms
F2. 3 périodes = 3*1/3300 = 0.90909 ms

Nombre d'échantillons durant 9.0909 ms :
T ech = 90.703 µs = 0.090703 ms
n = 0.90909/0.090703 = 10 'ce qu'on retrouve sur le graphe de la capture d'écran du bas, les calcus sont ok

10 échantillons pour décrire une courbe complexe c'est ketchi, il y a une sacrée perte d'informations. Me suis toujours demandé comment nos CD pouvaient reproduire une fréquence de 20 kHz avec seulement 2 points par période, y'a bien un phénomène que je ne capte pas, go back to school... Ou si tu as une idée ???



Edité par Christophe Le 14/03/2016 à 11h10
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 14/03/2016 à 12h28

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 516
Roland:
...il ne s'agit pas d'un fichier init, mais d'un simple branchement (décrit précédemment).


Bien vu, je ne l'avais pas vu, emporté par mon élan...
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Général » Générateur BF Ou qui tente de l'être  

 |  |

1 Utilisateur en ligne : 0 Administrateur, 0 Modérateur, 0 Membre et 1 Visiteur
Utilisateur en ligne : Aucun membre connecté
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie