CONNEXION
  • RetourJeux
    • Tests
    • Soluces
    • Previews
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Tous les Jeux
  • RetourActu
    • Culture Geek
    • Astuces
    • Réalité Virtuelle
    • Rétrogaming
    • Toutes les actus
  • Black Friday
  • RetourHigh-Tech
    • Actus JVTECH
    • Bons plans
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTECH
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch
    • Xbox Series
    • Overwatch 2
    • FUT 23
    • League of Legends
    • Genshin Impact
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • PS4
  • One
  • Switch
  • Wii U
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Etoile Abonnement RSS

Sujet : J'apprends openAL

News événement
La Manette d’Or 2024 : Voici comment s'inscrire au tournoi EA Sports FC 25 de la PS5
DébutPage précedente
1
Page suivantePage suivante
2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
11 juin 2024 à 11:40:36

Voilà toutes les fonctions dont j'ai besoin pour jouer un "bip":

alGetError()
alcGetString()
alcOpenDevice()
alcCreateContext()
alGenBuffers()
alBufferData()
alGenSources()
alSourcei()
alSourcePlay()
alGetSourcei()

Je me donne environ un mois pour essayer d'y comprendre quelque chose.

LGV LGV
MP
Niveau 24
11 juin 2024 à 11:51:23

Interet de multiplier les topics sans aucune plus-value ?

2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
11 juin 2024 à 12:54:31

Je vais essayer de comprendre quelque chose à ce tutoriel.

https://www.youtube.com/watch?v=BR8KjNkYURk

2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
11 juin 2024 à 13:19:52

Donc pour gérer la stereo il me faut cette fonction là en plus:

alSource3f()

Et pour le volume:

alSourcef()

Maintenant il faut que je repère quand est-ce que les sourceID ne sont plus valides car le son a fini de jouer.

Message édité le 11 juin 2024 à 13:21:22 par 2_power_Khey_1
2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
11 juin 2024 à 13:25:17

bon je suppose que ces trucs là doivent être appelés sur les audiothreads

2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
11 juin 2024 à 13:28:04

J'ai trouvé un sample sur stackoverflow je le tripote pour essayer de comprendre comment ça marche.

#include <al.h>
#include <alc.h>


#include <stdio.h>
#include <stdlib.h>    // gives malloc
#include <math.h>
#include <unistd.h>    // gives sleep

ALCdevice  * openal_output_device;
ALCcontext * openal_output_context;

ALuint internal_buffer;
ALuint streaming_source[1];

int al_check_error(const char * given_label) {

    ALenum al_error;
    al_error = alGetError();

    if(AL_NO_ERROR != al_error) {

        printf("ERROR - %s  (%s)\n", alGetString(al_error), given_label);
        return al_error;
    }
    return 0;
}

void MM_init_al() {

    const char * defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);

    openal_output_device  = alcOpenDevice(defname);
    openal_output_context = alcCreateContext(openal_output_device, NULL);
    alcMakeContextCurrent(openal_output_context);

    // setup buffer and source

    alGenBuffers(1, & internal_buffer);
    al_check_error("failed call to alGenBuffers");
}

void MM_exit_al() {

    ALenum errorCode = 0;

    // Stop the sources
    alSourceStopv(1, & streaming_source[0]);        //      streaming_source
    int ii;
    for (ii = 0; ii < 1; ++ii) {
        alSourcei(streaming_source[ii], AL_BUFFER, 0);
    }
    // Clean-up
    alDeleteSources(1, &streaming_source[0]);
    alDeleteBuffers(16, &streaming_source[0]);
    errorCode = alGetError();
    alcMakeContextCurrent(NULL);
    errorCode = alGetError();
    alcDestroyContext(openal_output_context);
    alcCloseDevice(openal_output_device);
}

void MM_render_one_buffer() {


    int seconds = 1;
    // unsigned sample_rate = 22050;
    unsigned sample_rate = 44100;
    size_t buf_size = seconds * sample_rate;

    // allocate PCM audio buffer
    float * samples = (float*)malloc(sizeof(float) * buf_size);

    int i=0;
    for(; i<buf_size; ++i) {

        samples[i] = ( ( i % 100 )*2.0-1.0 ) ;

    }

    /* upload buffer to OpenAL */
    alBufferData( internal_buffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
    al_check_error("populating alBufferData");

    free(samples);

    /* Set-up sound source and play buffer */
    // ALuint src = 0;
    // alGenSources(1, &src);
    // alSourcei(src, AL_BUFFER, internal_buffer);
    alGenSources(1, & streaming_source[0]);
    alSourcei(streaming_source[0], AL_BUFFER, internal_buffer);
    // alSourcePlay(src);
    alSourcePlay(streaming_source[0]);

    // ---------------------

    ALenum current_playing_state;
    alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
    al_check_error("alGetSourcei AL_SOURCE_STATE");

    while (AL_PLAYING == current_playing_state) {

        printf("still playing ... so sleep\n");

        sleep(1);   // should use a thread sleep NOT sleep() for a more responsive finish

        alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
        al_check_error("alGetSourcei AL_SOURCE_STATE");
    }

    printf("end of playing\n");

}   //  MM_render_one_buffer

int main() {

    MM_init_al();

    MM_render_one_buffer();

    /* Dealloc OpenAL */
    MM_exit_al();
}
2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
11 juin 2024 à 14:44:00

bon alors son pseudo-thread se trouve dans cette boucle:

    ALenum current_playing_state;
    alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
    al_check_error("alGetSourcei AL_SOURCE_STATE");

    while (AL_PLAYING == current_playing_state) {

        printf("still playing ... so sleep\n");

        sleep(1);   // should use a thread sleep NOT sleep() for a more responsive finish

        alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
        al_check_error("alGetSourcei AL_SOURCE_STATE");
    }

il faut faire le test == AL_PLAYING ailleurs que sur un sleep, je suppose que ça doit être placé bêtement dans la routine vidéo.

bon donc tout va se passer dans la gestion d'un tableau de "voix", je crois que le plus simple c'est de le gérer en pooling

2_power_Khey_1 2_power_Khey_1
MP
Niveau 4
12 juin 2024 à 07:52:31

bon je verrai plus tard le pooling de tracks car là c'est de l'algo,

voici le test final de "pouet" horrible qui se déplace de droite à gauche:

#include "Module.h"
#include "AL_Entry.h"

#include <al.h>
#include <alc.h>

#include <stdio.h>
#include <stdlib.h>    // gives malloc
#include <math.h>
#include <unistd.h>    // gives sleep

#include <iostream>
using namespace std;


ALCdevice  * openal_output_device;
ALCcontext * openal_output_context;

ALuint internal_buffer;
ALuint streaming_source[1];

int al_check_error(const char * given_label) {

    ALenum al_error;
    al_error = alGetError();

    if(AL_NO_ERROR != al_error) {

        printf("ERROR - %s  (%s)\n", alGetString(al_error), given_label);
        return al_error;
    }
    return 0;
}

void MM_init_al() {

    const char * defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);

    openal_output_device  = alcOpenDevice(defname);
    openal_output_context = alcCreateContext(openal_output_device, NULL);
    alcMakeContextCurrent(openal_output_context);

    // setup buffer and source

    alGenBuffers(1, & internal_buffer);
    al_check_error("failed call to alGenBuffers");

    cout << "id buffer: " << internal_buffer << endl;
}

void MM_exit_al() {

    ALenum errorCode = 0;

    // Stop the sources
    alSourceStopv(1, & streaming_source[0]);        //      streaming_source
    int ii;
    for (ii = 0; ii < 1; ++ii) {
        alSourcei(streaming_source[ii], AL_BUFFER, 0);
    }
    // Clean-up
    alDeleteSources(1, &streaming_source[0]);
    alDeleteBuffers(16, &streaming_source[0]);
    errorCode = alGetError();
    alcMakeContextCurrent(NULL);
    errorCode = alGetError();
    alcDestroyContext(openal_output_context);
    alcCloseDevice(openal_output_device);
}

void MM_render_one_buffer() {

    int seconds = 1;

    unsigned sample_rate = 44100;
    size_t buf_size = seconds * sample_rate;

    // allocate PCM audio buffer
    short * samples = (short*)malloc(sizeof(short) * buf_size);

    int i=0;
    float vol=1.0;
    for(; i<buf_size; ++i) {

        samples[i] = ( (i%128)/64.0 - 1.0 ) * (float)(1<<14) * vol ;
        vol *= .9999;

    }

    // update into buffer
    alBufferData( internal_buffer, AL_FORMAT_MONO16, samples, buf_size, sample_rate);
    al_check_error("populating alBufferData");

    free(samples);
}

void MM_prepare_source()
{
    alGenSources(1, & streaming_source[0]);
    cout << "id stream source: " << streaming_source[0] << endl;
}

void MM_play_one_buffer()
{

    alSourcei(streaming_source[0], AL_BUFFER, internal_buffer);
    alSourcePlay(streaming_source[0]);
}

// check playing routine

bool MM_is_buffer_playing()
{
    ALenum current_playing_state;
    alGetSourcei(streaming_source[0], AL_SOURCE_STATE, & current_playing_state);
    al_check_error("alGetSourcei AL_SOURCE_STATE");

    return (AL_PLAYING == current_playing_state);
}

// set pan

void MM_setPanVol( float pan, float vol )
{
    alSource3f( streaming_source[0], AL_POSITION, pan, 0, 4 );
    alSourcef( streaming_source[0], AL_GAIN, vol );
}



int main() {

    float vol = 1.0;
    float pan = -1.0;

    Module::Init();

    MM_init_al();

    // prepare wave
    MM_render_one_buffer();

    // prepare source
    MM_prepare_source();

    // play wave
    MM_play_one_buffer();


    // loop
    int STEP = 0;
    while ( STEP < 60*10 )
    {
        pan = cos( (double)STEP / 120.0 * M_PI ) * 14;
        STEP ++;

        if ( MM_is_buffer_playing() )
        {
            MM_setPanVol( pan, vol );
        }
        else
        {
            MM_play_one_buffer();
        }

        cout << "." ;
        usleep( 1000 * 16 );   // microseconds
    }
    cout << endl;

    /* Dealloc OpenAL */
    MM_exit_al();

    Module::ShutDown();

}

pour vous faire partager mes acouphènes je l'ai traduit en javascript:

const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// Create an empty three-second stereo buffer at the sample rate of the AudioContext

const sampleRate = 44100;

const myArrayBuffer_1 = audioCtx.createBuffer(
        1,
        sampleRate * .5,
        sampleRate,
        );

// Fill the buffer with white noise;
// just random values between -1.0 and 1.0

for (let channel = 0; channel < myArrayBuffer_1.numberOfChannels; channel++) {
    
    const nowBuffering = myArrayBuffer_1.getChannelData(channel);
    let vol = 1.0;
    for (let i = 0; i < myArrayBuffer_1.length; i++) {

        nowBuffering[i] = vol*( (i%128)/64.0 - 1 );
        vol *= .9999;
        
    }
}


var PAN = -1;

var PAN_NODE = null, GAIN_NODE = null;

var PLAYING = false;

function SoundTest( buffer )
{

    const source = audioCtx.createBufferSource();
    source.buffer = buffer;
    
    // end event
    
    source.onended = function( e )
    {
        PLAYING = false;
    };

   
    // pan-vol nodes
    PAN_NODE = audioCtx.createPanner();
    GAIN_NODE = audioCtx.createGain();
    
    GAIN_NODE.gain.setValueAtTime( 1, audioCtx.currentTime ); 
 
    // connect the AudioBufferSourceNode to the
    // destination so we can hear the sound
    
    source.connect(PAN_NODE);
    PAN_NODE.connect(GAIN_NODE);
    GAIN_NODE.connect(audioCtx.destination);

    // start the source playing
    //source.loop = true;
    source.start();

    PLAYING = true;
}

var STEP = 0;

function VideoRoutine( dt )
{       
    if ( ! PLAYING )
    {
        SoundTest( myArrayBuffer_1 );
    }
    STEP ++ ;
    
    // test vol-pan
    
    const pan = Math.cos( STEP / 120.0 * Math.PI ) * 16;
    
    PAN_NODE.positionX.setValueAtTime( pan, audioCtx.currentTime);
    PAN_NODE.positionY.setValueAtTime(   0, audioCtx.currentTime);
    PAN_NODE.positionZ.setValueAtTime(  4, audioCtx.currentTime);
    
    GAIN_NODE.gain.setValueAtTime( 1, audioCtx.currentTime ); 
    
    
    window.requestAnimationFrame(VideoRoutine);
}

const BTN_FX1 = document.getElementById("fx1");

BTN_FX1.onmousedown = function()
{
    VideoRoutine(16);
};

il semble que le panner node javascript a le même effet que AL_POSITION,

j'ai choisi amplitude -16 / 16 sur X, et profondeur 4 sur Z pour cet exemple

DébutPage précedente
1
Page suivantePage suivante
Répondre
Prévisu
?
Victime de harcèlement en ligne : comment réagir ?
La vidéo du moment