RSS ATOM

Oscillator
11/09/2014

Le code est dégueulasse mais montre comment générer un signal et l'envoyer à la carte son de façon très simple

Ce code est totalement libre. Vous pouvez faire un doner kebab avec si vous voulez.

  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
123
124
125
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <jack/jack.h>
#include <math.h>

#define PI 3.1415926

jack_client_t * client;
jack_port_t * output_port;

/*
Danc cet exemple l'idée est de générer la forme de l'onde une
et une seule fois et de le stocker dans un tableau
de la taille approprié qui soit un multiple du nombre
d'échantillons sortant. On procède ainsi pour gagner en
temps CPU et éviter de recalculer à la volé chaque
échantillons.

À chaque appelle de process() on incremente le curseur
sinusPointer pour accéder à la portion de l'onde à
envoyer stocké dans sinBuffer.
*/

int sinusPointer = 0;
jack_default_audio_sample_t sinBuffer[8192] = {0};

int process(jack_nframes_t nframes, void *arg) {
    // type float. Correspond au format de l'échantillons
    jack_default_audio_sample_t * out;
    
    // on récupère l'addresse de la mémoire tampons pour les échantillons
    // out est un tableau de 1024 entrée.
    out = jack_port_get_buffer(output_port, nframes);      
                                                            
    int i = 0;
    memcpy(
        out, 
        &sinBuffer[sinusPointer*1024], 
        1024 * sizeof(jack_default_audio_sample_t)
    );
    sinusPointer++;
    if (sinusPointer == 8)
            sinusPointer = 0;
    return 0;
}

/*
S'appuie en partie sur le code donnée en exemple
dans simple_client.c que vous pouvez consulter ici:

http://jackit.sourceforge.net/cgi-bin/lxr/http/
source/example-clients/simple_client.c
*/

void jack_shutdown(void *arg) {
        exit(1);
}

int initOscillator(
    char * client_name,
    jack_options_t options,
    jack_status_t * status,
    char *server_name
) {
    client = jack_client_open(client_name, options, status, server_name);
    
    if (client == NULL)
            return -1; 
    jack_set_process_callback(client, process, 0); 
    jack_on_shutdown(client, jack_shutdown,0);
    
    output_port = jack_port_register(
        client,
        "Main Signal",
        JACK_DEFAULT_AUDIO_TYPE,
        JackPortIsOutput,
        0
    ); 
    
    if (output_port == NULL)
            return -2; 
    
    if (jack_activate(client))
            return -3; 
    
    return 0;
}

int main(int argc, char** argv) {
    jack_status_t status;
    char * server_name = NULL;
    int i=0;
    for(i=0; i<8192;i++) {
            sinBuffer[i] = sinf(2 * PI/128.0 * i ) * 0.1;
    }
    int err = initOscillator(
        "Oscillator", 
        JackNullOption, 
        &status, 
        server_name
    );
    
    if (err == -1){
            printf("jack_client_open() failed.\n");
            if (status & JackServerFailed) {
                    printf ("Unable to connect to JACK server.\n");
            }
            exit(-1);
    }
    else if (err == -2) {
            printf("Main output signal port cannot be create.\n");
            exit(-2);
    }
    else if (err == -3) {
            printf("Cannot activate Oscillator.\n");
            exit(-3);
    }
    
    sleep(-1);
    
    jack_client_close(client);
    exit(0);
}