IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[VisualC++][audio] générer un son


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 60
    Par défaut [VisualC++][audio] générer un son
    Bonjour à tous,

    Je cherche une lib me permettant de générer un son.
    Par "générer un son", j'entend un son continu dont je puisse préciser la fréquence, le volume et la balance.
    Toutes les libs que j'ai trouvé ne permettent que de lire des fichiers wav ou autres.
    J'ai l'impression que DirectX permet çà, mais çà à l'air lourd à gérer pour si peu.

    Bref, des idées, suggestions, pistes ?

    Merci d'avance,
    Yéyé

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    bonjour,

    as-tu jeté un coup d'oeil sur OpenAL?
    Sinon effectivement, directX permet de faire ça.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 60
    Par défaut
    merci,

    mais celle-ci a l'air trop haut niveau pour ce que je veux faire : je veux vraiment maitriser ce que j'envoie sur chaque HP. Cette lib est plutot orientée son 3D on dirait.

    Merci quand meme,
    Yéyé

  4. #4
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Citation Envoyé par _yeye_ Voir le message
    Par "générer un son", j'entend un son continu dont je puisse préciser la fréquence, le volume et la balance.
    Toutes les libs que j'ai trouvé ne permettent que de lire des fichiers wav ou autres.
    J'ai l'impression que DirectX permet çà, mais çà à l'air lourd à gérer pour si peu.
    Regarder les API multimédias notamment de waveform.
    PAr exemple waveOutSetPitch permet de régler le pitch

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 60
    Par défaut
    Désolé d'avoir tardé à répondre.
    Ca avait l'air interressant, mais ça ne marche pas : ma carte ne gère apparement pas la gestion du pitch.

    Merci quand meme,
    Yéyé

  6. #6
    Inactif  

    Homme Profil pro
    Ingénieur test de performance
    Inscrit en
    Décembre 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur test de performance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 986
    Par défaut
    Bonjour.

    Citation Envoyé par _yeye_ Voir le message

    J'ai l'impression que DirectX permet çà, mais çà à l'air lourd à gérer pour si peu.
    Désolé de réagir, mais la lecture d'un format audio n'a rien de comparable à du "si peu".

    Essaies d'écrire un programme complet qui gère la lecture d'un format audio, ne serait-ce que le wave, et tu comprendras de quoi je parle.

    De plus voici un exemple de lecture de n'importe quel format audio (à condition d'avoir les codecs audio) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    HRESULT Play(const wstring& wszFile){
     
    	CComPtr<IGraphBuilder> pGraph;
    	CComPtr<IMediaControl> pMediaCtrl;
    	CComPtr<IMediaEventEx> pEventEx;
     
    	if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
    				                         reinterpret_cast<void**>(&pGraph))))
    	  return E_FAIL;
     
    	if(FAILED(pGraph->RenderFile(wszFile.c_str(), NULL)))
    		return E_FAIL;
     
    	if(FAILED(pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&pMediaCtrl))))
    		return E_FAIL;
    	if(FAILED(pGraph->QueryInterface(IID_IMediaEventEx, reinterpret_cast<void**>(&pEventEx))))
    		return E_FAIL;
     
    	if(FAILED(pMediaCtrl->Run()))
    		return E_FAIL;
     
    	long EvCode;
     
    	pEventEx->WaitForCompletion(INFINITE, &EvCode);
     
    	return S_OK;
    }
    Une fois que tu as écris ces 16 lignes de code, il suffit d'une seule ligne de code pour écouter un fichier audio :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Play("Mon fichier audio");
    Si c'est considéré comme du du lourd, alors je ne sait plus quoi dire...

    PS : et pour gérer les balances, volumes et autres, ce ne sont que quelques lignes de plus...

    PS2: je reconnais que la façon dont DirectShow est présentée, puisse sembler très compliquée. Pourtant, pour des traitements comme tu souhaiterais en faire, elle est tout à fait abordable avec un maximum de possibilités. Je prépare d'ailleurs des tutoriaux sur le sujet, et le code ci-dessus en fait parti. Le premier est déjà en ligne, il explique les étapes de compilation pour cette API :

    http://moldavi.developpez.com/tutorial/diretcshow1/

    Les tutoriaux suivants vont bientôt suivre.

  7. #7
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Je cherche une lib me permettant de générer un son.
    Par "générer un son", j'entend un son continu dont je puisse préciser la fréquence, le volume et la balance.
    Le programme suivant permet d'envoyer un signal quelconque (dont l'équation x(t) est donnée) vers la carte son. Dans l'exemple ci-présent, on génère un son pur (sinusoïde) de fréquence 1kHz, d'amplitude 100% (1), et de durée T = 2 s (2000 ms).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    /* sound_gen.c */
     
    #include <stdio.h>
    #include <windows.h>
    #include <mmsystem.h>
    #include <math.h>
    #include <limits.h>
    #include <stdlib.h>
     
    #define WAV_2_PI 6.283185307179586476925286766559 /* 2 * PI */
     
    double sin_1000(double t);
    char * echantillonner(double (*x)(double), unsigned fe, unsigned T, unsigned * pCount, char ** pBuffer);
    MMRESULT wav_open_device(u_int device_id, unsigned fe, HWAVEOUT * ptr);
    MMRESULT wav_write(HWAVEOUT hWaveOut, WAVEHDR * pwhdr, char * buffer, DWORD buf_size, u_int nLoops);
    MMRESULT wav_cleanup(HWAVEOUT hWaveOut, WAVEHDR * pwhdr);
    MMRESULT wav_close_device(HWAVEOUT hWaveOut);
     
    int main()
    {
        unsigned fe = 44100; /* Frequence d'echantillonnage en Hz */
        HWAVEOUT hWaveOut;
     
        if (wav_open_device(WAVE_MAPPER, fe, &hWaveOut) != MMSYSERR_NOERROR)
            fprintf(stderr, "La fonction wav_open_device a echoue.\n");
        else
        {
            double (*x)(double) = sin_1000; /* Le signal a traiter (x(t)) */
            unsigned T = 2000; /* duree de l'observation en ms (t0 = 0 ms) */
            unsigned N; /* Nombre d'echantillons */
            char * buffer;
     
            if ((echantillonner(x, fe, T, &N, &buffer)) == NULL)
                fprintf(stderr, "La fonction echantillonner a echoue.\n");
            else
            {
                WAVEHDR whdr; /* Requis par wav_write et wav_cleanup */
     
                wav_write(hWaveOut, &whdr, buffer, N, 1);
                printf("Press ENTER to stop.\n");
                getchar();
                wav_cleanup(hWaveOut, &whdr);
     
                free(buffer);
            }
     
            wav_close_device(hWaveOut);
        }
     
        return 0;
    }
     
    double sin_1000(double t) /* signal sinusoidal de frequence 1kHz */
    {
        /* t en ms (=> t / 1000 en s) */
        return sin(WAV_2_PI * 1000 * (t / 1000));
    }
     
    char * echantillonner(double (*x)(double), unsigned fe, unsigned T, unsigned * pCount, char ** pBuffer)
    {
        /* fe : Frequence d'echantillonnage en Hz (=> 1 / fe en s)*/
        /* T : duree de l'observation en ms */
     
        unsigned N; /* Nombre d'echantillons */
        double Te = 1000.0 / fe; /* Periode d'echantillonnage en ms */
        char * buffer;
     
        N = (unsigned)(T / Te);
     
        if ((buffer = malloc(N)) != NULL)
        {
            unsigned k;
     
            /* Le signal x(t) doit etre / -1 <= x(t) <= 1 */
            /* Un echantillon xk = x(k * Te) doit etre tel que 0 <= xk <= UCHAR_MAX */
     
            for(k = 0; k < N; k++)
                buffer[k] = (char)((1 + x(k * Te)) * (UCHAR_MAX / 2));
        }
     
        *pCount = N;
        *pBuffer = buffer;
     
        return *pBuffer;
    }
     
    MMRESULT wav_open_device(u_int device_id, unsigned fe, HWAVEOUT * ptr)
    {
        WAVEFORMATEX wfex;
     
        wfex.wFormatTag      = WAVE_FORMAT_PCM;
        wfex.cbSize          = 0;
        wfex.nChannels       = 1; /* Mono. 2 = Stereo */
        wfex.wBitsPerSample  = CHAR_BIT; /* Nombre de bits par echantillon */
        wfex.nBlockAlign     = (wfex.nChannels * wfex.wBitsPerSample) / CHAR_BIT;
        wfex.nSamplesPerSec  = fe;
        wfex.nAvgBytesPerSec = fe * wfex.nBlockAlign;
     
        return waveOutOpen(ptr, device_id, &wfex, 0, 0, 0);
    }
     
    MMRESULT wav_write(HWAVEOUT hWaveOut, WAVEHDR * pwhdr, char * buffer, DWORD cbBuffer, u_int nLoops)
    {
        ZeroMemory(pwhdr, sizeof(*pwhdr));
        pwhdr->lpData = buffer;
        pwhdr->dwBufferLength = cbBuffer;
        pwhdr->dwLoops = nLoops;
     
        waveOutPrepareHeader(hWaveOut, pwhdr, sizeof(*pwhdr));
        return waveOutWrite(hWaveOut, pwhdr, sizeof(*pwhdr));
    }
     
    MMRESULT wav_cleanup(HWAVEOUT hWaveOut, WAVEHDR * pwhdr)
    {
        waveOutUnprepareHeader(hWaveOut, pwhdr, sizeof(*pwhdr));
        return waveOutReset(hWaveOut);
    }
     
    MMRESULT wav_close_device(HWAVEOUT hWaveOut)
    {
        return waveOutClose(hWaveOut);
    }
    - Il faut se lier avec winmm.lib
    - C'est du C (désolé), mais tu peux facilement l'adapter pour le C++
    - C'est le genre de code qu'on utilise pour implémenter les fonctions permettant de lire un fichier wav (ouvrir le fichier, lire le son, fermer le fichier)

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 60
    Par défaut
    moldavi -> hum, je ne voulais absolument pas dénigrer la programmation audio, mais utiliser DirectX juste pour émettre un bip me semblait disproportionné. Je jetterai un œil sur tes tutos

    Melem -> très intéressant, faudra que j'épluche çà demain. Si en plus le buffer permet de préciser le volume sur chaque canal (gauche et droit) alors bingo, c'est exactement ce que je cherche :o)

    Merci à tous les 2,
    Yéyé

  9. #9
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par _yeye_ Voir le message
    Melem -> très intéressant, faudra que j'épluche ça demain. Si en plus le buffer permet de préciser le volume sur chaque canal (gauche et droit) alors bingo, c'est exactement ce que je cherche :o)
    Le volume sur chaque canal ... les signaux que tu envoies sur chaque canal ne sont même pas nécessairement les mêmes ! Le volume est contrôlé par l'amplitude du signal. L'exemple est en mono, mais il n'y a pas grand chose à changer pour passer au stéréo : modifier la valeur de wfex.nChannels (2 pour stéréo) puis fournir un buffer adéquat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    buffer[0] = left[0];
    buffer[1] = right[0];
     
    buffer[2] = left[1];
    buffer[3] = right[1];
     
    etc.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 60
    Par défaut
    Ca l'air de marcher plutot pas mal.
    Un truc bizarre quand meme : si j'envoie un signal à gauche et rien à droite (tout à zéro), j'entend quand meme légèrement le signal à droite (et vice-versa) ... mais bon, léger, hein !

    Par contre, pour faire varier la fréquence en live va falloir que je triture le buffer pendant qu'il est lu .... hum, ça va être chaud ça

    Merci en tout cas,
    Yéyé

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Audio] capture de son
    Par catstevens01 dans le forum Multimédia
    Réponses: 0
    Dernier message: 21/07/2008, 11h13
  2. [son] générer un son
    Par _yeye_ dans le forum SDL
    Réponses: 1
    Dernier message: 10/06/2008, 19h45
  3. [Audio]Problème de son avec carte TV Pinnacle
    Par arnaud_verlaine dans le forum Périphériques
    Réponses: 2
    Dernier message: 14/09/2006, 14h09
  4. Problème Audio --> Plus de son ... :-(
    Par snoopy69 dans le forum Composants
    Réponses: 3
    Dernier message: 19/02/2006, 00h39
  5. [Audio]Jouer un son .au
    Par Pill_S dans le forum Multimédia
    Réponses: 11
    Dernier message: 28/12/2004, 17h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo