Forum Liberty Basic France

Général » Générateur BF Ou qui tente de l'être
Le 14/03/2016 à 12h28

Modérateur

Groupe: Modérateur

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

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

   
Le 14/03/2016 à 16h28

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
comment nos CD pouvaient reproduire une fréquence de 20 kHz avec seulement 2 points par période

Si tu découpe du 20 Hz en 44100 rondelles; ça fait un sacré paquet de points
Et même en 11000 rondelles; ça en fait encore un sacré paquet
Il y a un os dans ton raisonnement
____________________
Roro

   
Le 14/03/2016 à 20h13

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Certes, ça doit faire quelques kilos. Mais de Hertz il n'est point question puisque c'est en kiloHerz que mon vingt était exprimé, du coup les kilos s'annulent (contrairement à ce qui se passe dans la vraie vie au fil du temps) et il reste le ratio 44,1/20, ce qui nous donne, à vue de nez, deux rondelles et quelques brouettes... ;)
____________________
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 à 21h00

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
c'est en kiloHerz que mon vingt était exprimé

En effet; mais à 20kHz, on est à la limite de l'audition, et pour ceux qui ont une bonne (excellente) oreille
Le si au 9eme octave (le piano n'en a que 7) est à 15 804 Hz
Et donc, deux rondelles doivent faire l'affaire
____________________
Roro

   
Le 15/03/2016 à 15h09

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
C'est vrai, mais le défaut est bien audible et visible sur les captures d'écran à 4400 Hz, il doit quand-même y avoir un os dans le raisonnement. Comme ce n'est qu'une histoire d'équations à changer ou modifier, je finalise les fonctions du programme et on verra après. A moins qu'une âme charitable passe avec la solution sur un plateau... ;)
____________________
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 17/03/2016 à 16h07

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Faut sans doute savoir se rendre à l'évidence. J'ai créé dans Audacity une fréquence de 3300 Hz et une de 4400 Hz, j'ai exporté le mélange en wav, et j'obtiens :



Toute ressemblance avec une précédente capture d'écran ne semble pas vraiment fortuite...
____________________
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 17/03/2016 à 18h59

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Lol ! Toutes choses étant égales par ailleurs, il n'y a pas de raison de trouver de différence (La Palisse inside)
____________________
Roro

   
Le 18/03/2016 à 16h39

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Alors du coup je continue tranquille et serein sur la section le codage 16 bits. Après avoir découvert qu'il fallait dans ce mode des entiers signés, je me retrouve avec ce type de résultat (les croix rouges indiquent "ce qui devrait être", selon Saint-Moi) :



les alternances positives sont correctes
les alternances négatives semblent "redressées" comme par un pont de diode, et elles sont centrées sur les plus petites valeurs possible (vers les -32767) au lieu du zéro, donc c'est bizarre mais globalement je ne suis pas très loin du résultat (probablement une histoire de complément à 2 où, pour le moment, je ne vois pas de grande différence avec la méthode du bit réservé au signe. Enfin, j'étudie).

Voilà pour Lénouvelle-Dufront, je continue...



Edité par Christophe Le 18/03/2016 à 16h43
____________________
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 20/03/2016 à 00h53

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
C'était bien un problème de complément à 2. ( Pour plus d'explication )

Il faudrait inclure la fréquence d'échantillonnage dans le calcul de la période commune : en l'état actuel on dénote un (très) léger décalage à la jointure entre deux périodes quand on zoome avec audacity.

Je réfléchis à un niveau automatique, qui mettrait systématiquement 'à pleine échelle' le signal généré. Les cases "volume" ne serviraient qu'au ratio des entre les deux fréquences... Utile, ou pas ?



Edité par Christophe Le 20/03/2016 à 00h59
____________________
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 20/03/2016 à 08h58

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Un réglage de volume genre "balance" n'exonère pas d'un réglage général
Mais c'est pas mal comme idée.
____________________
Roro

   
Le 20/03/2016 à 10h47

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Suite:
Au lieu de rechercher le bon échantillonnage, n'est-il pas préférable de rechercher la période approchée divisible par l'échantillonnage (imposé)
Quitte à afficher la valeur de la correction
Il serait intéressant de connaître la valeur max de la correction nécessaire.
Qu'en pense-tu ?
____________________
Roro

   
Le 21/03/2016 à 12h46

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Citation:
Un réglage de volume genre "balance" n'exonère pas d'un réglage général

Ajouté à la liste des choses à réflexitudiser^^

Citation:
Au lieu de rechercher le bon échantillonnage, n'est-il pas préférable de rechercher la période approchée divisible par l'échantillonnage (imposé)
Quitte à afficher la valeur de la correction
Il serait intéressant de connaître la valeur max de la correction nécessaire.

Modifier légèrement les fréquences entrées dans les textbox pour qu'il y ait correspondance avec la fréquence d'échantillonnage, et les afficher en statictext à coté ?

On peut aussi envisager de continuer les calculs jusqu'à la coincidence entre les trois fréquences, il n'y aura plus besoin d'approcher une valeur.

Il est probable que ça fasse une floppée de calculs en plus, du coup j'ai aussi envie de voir une solution à base de PGCD des trois fréquences, on tombera alors directement sur la bonne durée, divisible par la fréquence d'échantillonnage. C'est tout un programme à concevoir, ça nous limitera aux fréquences entières, mais c'est pas hors de portée.

Je réfléchis...
____________________
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 21/03/2016 à 19h49

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Bon, bah, comme souvent, c'était tout con, et comme souvent, j'ai tourné un bout de temps... :clap

pgcd de 3 nombres :
Code VB :
 
n1=1000
n2=2319
n3=44100
 
n1=2*2*2*3*5*7
n2=2*2*3*5*7
n3=2*2*3*3*7*41
 
a$=""
diviseur=2
 
print "recherche pgcd de :",n1,n2,n3
 
 
 
fin=0
tour=0
 
while fin=0
 
    if n1 mod diviseur =0 and n2 mod diviseur =0 and n3 mod diviseur =0 then
        'si la division des trois nombres par "diviseur" donnent trois entiers
        'alors "diviseur" est un facteur commun à ces nombres
        'on l'ajoute à a$
        a$=a$+str$(diviseur)+"*"
        'et on calcule les nombres pour le tour suivant
        n1=n1/diviseur
        n2=n2/diviseur
        n3=n3/diviseur
        print diviseur;" = facteur commun",n1,n2,n3
    else
        'sinon on ajoute 1 à divis pour le calcul suivant (diviseur n'a pas a être premier, puisqu'il est de + en + grand
        'print diviseur;" = pas commun"
        diviseur=diviseur+1
    end if
 
    'sortie de la boucle quand l'un au moins des nombres est devenu inférieur au diviseur
    'ou à partir d'un diviseur dont il est vraiscemblable qu'on ira jamais jusque là
    tour=tour+1
    if tour=100000 or (n1<diviseur or n2<diviseur or n3<diviseur)then fin=1
 
wend
 
print
print left$(a$,len(a$)-1)
 
 


il n'y a plus qu'à lire a$ pour connaitre le pgcd. Peut-être même que je pourrais le calculer directement, au fil de la boucle.

Tout ça pour ça, t'avoueras... Je ne sais même plus pourquoi je voulais ce pgcd, et Je m'en vais de ce pas retrouver une activité plus normale... A+



Edité par Christophe Le 21/03/2016 à 19h51
____________________
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 21/03/2016 à 21h13

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
Je ne sais même plus pourquoi je voulais ce pgcd

Loooooleuuu!!!!
C'était pour harmoniser l'échantillonnage et les périodes
Tu aurais pu afficher la freq d'ech résultante dans ton super calculateur de PGCD
Et le: 2*2*3*7 qui se pointe à la fin, je n'ai pas creusé; c'est quoi au juste ?
____________________
Roro

   
Le 22/03/2016 à 12h45

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
le nombre magique qui divise les autres :top ('me suis amusé avec les commentaires)

L'intégration du pgcd dans le programme a été bien plus facile.

Le voici quelque peu remanié, cela semble fonctionner (je n'ai pas testé toutes les associations de fréquences, donc ça reste encore bien théorique au niveau du "ça fonctionne", hein ?)
Code VB :
 
'Géné BF 2 fréquences
'22 mars 2016 - 12h34

'ajout affichage forme d'onde : à revoir pour l'affichage du dernier point
'réglage d'amplitude manuel et automatique, balance gen1/gen2 : restent à créer

 
    '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
    dim affichage(largeurvisu)
    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
 
 
[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
    'calcul du nombre d'échantillons audio de la période
    tEchant=1/fEchant
    nbrEchant=fEchant/pgcd(freq1,freq2,fEchant)
 
    'et du nombre de fois où elle sera répétée pour obtenir la durée souhaitée
    repetitions=duree/(nbrEchant*tEchant)
    if duree mod nbrEchant*tEchant <> 0 then repetitions=int(repetitions)+1
    print "il y aura ";repetitions;" fois la période de la somme"
 
    'visualiser la période
    gosub [visu]
 
    '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
 
    if horslimite=0 then
        '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$
 
    else
        notice "Valeurs hors-limite trouvée, le fichier wave n'est pas généré"
    end if
 
    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 nbrEchant-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 nbrEchant-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]"
    horslimite=0
 
 
 
    '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 -32767 à +32768
    '
    print "échantillon définitif, octetFort, octetFaible, contrôle"
 
    for a=0 to nbrEchant-1
 
        'calculer l'échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
 
        echantillon=somme*65535/amplitudemax   'échantillons

        'arrondir l'échantillon
        entiere=int(echantillon)
        decimale=echantillon-int(echantillon)
 
        echantillon=entiere
        if decimale>=0.5 then echantillon=entiere+1
        if decimale<=-0.5 then echantillon=entiere-1
 
        'convertir l'échantillon
        if echantillon<0 then
            'en dessous de zéro
            echantillon=2^15-abs(echantillon)
            octetFort = abs(int(echantillon/256)+128)
            octetFaible = echantillon mod 256
        else
            'zéro et plus
            octetFort=int(echantillon/256)
            octetFaible=echantillon mod 256
            verif=octetFort*256+octetFaible
        end if
 
        'verifs
        'print echantillon,octetFort,octetFaible, verif

        'enregistrement
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
    t=t+tEchant
    next
 
return
 
 
[fichier_16bits_stereo]
        print "[fichier_16bits_mono]"
    for a=0 to nbrEchant
 
        'voie gauche
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
 
        echantillon=somme*65535/amplitudemax   'échantillons

        'arrondir l'échantillon
        entiere=int(echantillon)
        decimale=echantillon-int(echantillon)
 
        echantillon=entiere
        if decimale>=0.5 then echantillon=entiere+1
        if decimale<=-0.5 then echantillon=entiere-1
 
        'convertir l'échantillon
        if echantillon<0 then
            'en dessous de zéro
            echantillon=2^15-abs(echantillon)
            octetFort = abs(int(echantillon/256)+128)
            octetFaible = echantillon mod 256
        else
            'zéro et plus
            octetFort=int(echantillon/256)
            octetFaible=echantillon mod 256
            verif=octetFort*256+octetFaible
        end if
 
        'verifs
        'print echantillon,octetFort,octetFaible, verif

        'enregistrement
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        'voie droite
        'calcul échantillon
        somme=vol1*sin(omega1*t)+vol2*sin(omega2*t)
 
        echantillon=somme*65535/amplitudemax   'échantillons

        'arrondir l'échantillon
        entiere=int(echantillon)
        decimale=echantillon-int(echantillon)
 
        echantillon=entiere
        if decimale>=0.5 then echantillon=entiere+1
        if decimale<=-0.5 then echantillon=entiere-1
 
        'convertir l'échantillon
        if echantillon<0 then
            'en dessous de zéro
            echantillon=2^15-abs(echantillon)
            octetFort = abs(int(echantillon/256)+128)
            octetFaible = echantillon mod 256
        else
            'zéro et plus
            octetFort=int(echantillon/256)
            octetFaible=echantillon mod 256
            verif=octetFort*256+octetFaible
        end if
 
        'verifs
        'print echantillon,octetFort,octetFaible, verif

        'enregistrement
        periodesomme$=periodesomme$+chr$(octetFaible)+chr$(octetFort)
 
        t=t+tEchant
    next
 
    return
 
 
[visu]
    print "[visu]"
 
    'calcul durée de la période reproductible
    affperiode=1/pgcd(freq1,freq2,freq1)
    pas=affperiode/largeurvisu
 
    'calcul échantillons et limites pour visu
    minaff=0:maxaff=0
 
    for a=0 to largeurvisu-1
        ta=a*pas
        affichage(a)=vol1*sin(omega1*ta)+vol2*sin(omega2*ta)
        if affichage(a)>maxaff then maxaff=affichage(a)
        if affichage(a)<minaff then minaff=affichage(a)
    next a
 
    amplitude=maxaff-minaff
    amplitudegraf=hauteurvisu-30
    pasy=amplitudegraf/amplitude
    yzero=25+amplitudegraf/2
 
    'affichage de la période
    print #1.visu, "color cyan"
    print #1.visu, "down"
    print #1.visu, "cls"
    print #1.visu, "fill darkgray"
 
    print #1.visu, "place 10 15"
    print #1.visu, "backcolor darkgray"
    duree$=using("#####.###",affperiode*1000)
    print #1.visu, "\durée : ";duree$;" ms"
 
    print #1.visu, "place 0 ";yzero;" "
 
    for a=0 to largeurvisu-1
        ech=affichage(a)*pasy
        'print "visu, élément ";a;"  : ";ech;" affiché en ";yzero-ech
        print #1.visu, "goto ";a;" ";yzero - ech
        'print "bhem goto ";a;" ";yzero - ech
    next
 
    'dessin axe y
    print #1.visu, "color lightgray"
    print #1.visu, "line 0 ";yzero;" ";largeurvisu;" ";yzero
    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
 
 
function pgcd(n1,n2,n3)
 
    diviseur=2
    pgcd=1
    fin=0
    tour=0
 
    while fin=0
 
        if n1 mod diviseur =0 and n2 mod diviseur =0 and n3 mod diviseur =0 then
            pgcd=pgcd*diviseur
            n1=n1/diviseur
            n2=n2/diviseur
            n3=n3/diviseur
            'print diviseur;" = facteur commun",n1,n2,n3
        else
            'print diviseur;" = pas commun"
            diviseur=diviseur+1
        end if
 
        'sortie de la boucle quand l'un au moins des nombres est devenu inférieur au diviseur
        'ou à partir d'un diviseur dont il est vraiscemblable qu'on ira jamais jusque là
        tour=tour+1
        if tour=100000 or (n1<diviseur or n2<diviseur or n3<diviseur)then fin=1
 
    wend
 
end function
 

Maintenant je souffle un petit peu.
____________________
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/06/2016 à 19h46

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Hello, c'est moi !

Le projet avance, et la fin se profile à l'horizon. Mais l'horizon étant ce qu'il est, plus on cherche à s'en rapprocher, plus il s'éloigne, et ça peut durer longtemps... mais on avance, il n'y a pas de problèmes insurmontables, et les trucs étranges se résolvent d'eux-meme après une étude attentive du code. Il y en a encore quelques uns.

Probable aussi que l'histoire du pgcd et avant, du ppcm, n'avait pas grande importance si on parle en fréquences et durées entières : au bout d'une seconde, quelles que soient les fréquences en jeu, on aura fait le tour de la courbe résultante. Pas très sûr de ce que j'avance mais je n'ai jamais été très doué en maths. Et la méthode du pgcd permet de connaitre la plus petite durée définissant la période d'une somme de fréquences, ce qui peut parfois être utile, donc je le laisse en l'état.

Il n'y aurait pas beaucoup de sens à publier le code aujourd'hui, même en zip. Le programme en est à un peu plus de 1000 lignes, il y a beaucoup de codes redondants qui mériteraient d'être placés dans des boucles, et c'est encore le chantier. Les potentiomètres ont été abandonnés au profit d'un système "clic gauche pour diminuer/clic droit pour augmenter" appliquable sur chaque chiffre individuellement, c'est "un peu lent" mais satisfaisant.

Le travail actuel est sur l'affichage de la courbe, avec au choix l'affichage de la courbe idéale, ou telle qu'elle se trouve dans le fichier, et l'apparition de voyants pour signaler qu'une même colonne de pixels affiche plusieurs échantillons, donc que l'affichage peut être faux, et un autre détail qui m'échappe actuellement. Il n'y aura pas de zoom, sauf peut-être dans une hypothétique version 2.

Voilà pour les nouvelles.

A+
____________________
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/06/2016 à 08h41

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Lol ! Il faut que l'affichage soit juste, autant que faire se peut
Pour zoomer il faut augmenter la vitesse de balayage( ou diminuer la fréquence) et augmenter le niveau
En ne touchant qu'à l'affichage. of course
____________________
Roro

   
Le 10/06/2016 à 19h14

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
La
____________________
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 10/06/2016 à 19h29

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Non, ici, c'est quoi ce bintz ???, j'écris "La" et le forum considère que ma prose se résume à ça ? nan mais ho, des fois !

En effet on ne touche qu'à l'affichage.

Donc, je reprend le "La" du post précédent et je continue "courbe à afficher sera très probablement préparée dans un tableau pendant le calcul de la vraie courbe. C'est déjà le cas, sauf que c'est actuellement rudimentaire. S'il y a un zoom à faire, ce sera entre tel et tel indice si on parle de temps (l'axe horizontal), et entre telle et telle valeur si on parle de valeurs (l'axe vertical)".

En fait, le but de l'affichage "idéal"/"réel" est de mettre en évidence une dent de scie là ou les calculs donnent de jolies courbes, lorsqu'on s'approche de la moitié de la fréquence d'échantillonnage. Il n'y aurait aucune perte d'information tant qu'on numérise un signal dont la fréquence va jusqu'à la moitié de la fréquence d'échantillonnage, et à l'oreille, eh bien j'y crois pas trop; Donc comme je ne capte rien à la logique de ce théorème, je laisse le choix d'afficher la courbe réelle, ou celle dans le fichier.

voiça
____________________
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 10/06/2016 à 21h31

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2264
Citation:
mettre en évidence une dent de scie là ou les calculs donnent de jolies courbes

Tu parle de faire un affichage de l'état logique
mais ce qui sort et qu'on veut représenter, c'est de l'analogique (son des hauts parleurs)
Il est donc logique d'afficher de l'analogique, en passant par le numérique (comme pour le son)
Tu vire vers l'oscillo à échantillonnage
Si tu laisse le choix, c'est nickel.
____________________
Roro

   
Le 18/06/2016 à 16h24

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 619
Pas touché au procédé d'affichage de la courbe, toujours calculée en fonction de la largeur de la fenêtre de visu. Ce n'est donc pas forcément l'allure de la courbe stockée dans le fichier.

par contre j'ai innové dans la présentation des données :

les paramètres du fichier wav sont maintenant dans une fenêtre qu'on ouvre par le bouton adéquat, et qu'on peut ouvrir et refermer à volonté. Dommage collatéral : je n'arrive pas à récupérer la valeur d'une textbox. Pas de souci pour les combobox.

La seconde différence est la gestion des fréquences, balance et volume global par clic de souris sur les chiffres.

La troisième me chagrine un peu : vu la taille de plus en plus conséquente, j'ai dû placer le fichier dans un zip (c'était tellement commode de placer le code tel quel entre les balises et qu'on pouvait prendre par un simple copier-coller)

Enfin, voici, avec probablement quelques bugs mais normalement ça fonctionne :
gbf 18juin2016_1ab2b.zip
____________________
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