Kirjoittaja Aihe: Mikrofonin syöte c++ -taulukkoon  (Luettu 158 kertaa)

teele

  • Käyttäjä
  • Viestejä: 901
    • Profiili
Mikrofonin syöte c++ -taulukkoon
« : 21.11.25 - klo:18.06 »

Kun koneen mikrofoni kuulee ääntä, tämä muutettaneen jossain vaiheessa digitaaliseksi eli numeroiksi.

Miten saisi tällaisia mikrofonilta peräisin olevia numeroita esimerkiksi 100-paikkaiseen taulukkoon aina tietyin aikavälein, kun koneessa on 24.04 Ubuntu.

Millaisella nopeudella tai taajuudella näitä digitalisoituja numeroita tulee 24.04 Ubuntussa ja saisiko vaikka kaikki 100 peräkkäistä arvoa taulukkoon niin, että se olisi kohtuullisen kevyt toiminto suorittimelle tai väylälle tai muille asiaan liittyville laitteille.

En tunne digitaalista äänitekniikkaa Ubuntussa yhtään, joten ihan käytännönselitykset olisivat  tervetulleita.


nm

  • Käyttäjä
  • Viestejä: 16853
    • Profiili
Vs: Mikrofonin syöte c++ -taulukkoon
« Vastaus #1 : 21.11.25 - klo:20.26 »
Äänipiirin AD-muunnin muuntaa mikrofonilta tulevan analogisen signaalin digitaaliseksi PCM-signaaliksi. Esimerkiksi tyypillisessä CD-laatuisessa äänessä näytteenottotaajuus on 44 100 Hz ja käytössä on 16-bittiset näytteet, eli yhden sekunnin mittaisessa digitaalisessa tallenteessa on 44 100 kpl 16-bittisiä numeroita (0-65535). CD-äänessä on lisäksi kaksi erillistä kanavaa (stereo). Mikrofonilta tulevassa äänessä on tyypillisesti yksi kanava tai monoääni on kahdennettu kahdelle kanavalle.

Mainitsemaasi 100 paikan taulukkoon voi siis tallentaa 2,3 millisekuntia CD-laatuista monoääntä. 44 100 paikan taulukkoon voit tallentaa 1 sekunnin verran ääntä ja 2 646 000 paikan taulukkoon 1 minuutin pätkän. 16-bittisenä sekunnin pätkä tarvitsee muistia tai tallennustilaa 88 200 tavua eli 86 kt ja minuutin pätkään tarvitaan 5 292 000 tavua eli reilut 5 Mt. Tällaisten datamäärien käsittely on nykyisille tietokoneille täysin triviaalia. Esimerkiksi Full HD -näytölle piirrettävän 60 Hz RGB-signaalin datamäärä on yli 4000 kertaa isompi (356 Mt/s), ja sekin on tänä päivänä pientä lämmittelyä, kun erillisten näytönohjainten ja tehokkaimpien prosessorien muistiväylät ovat parhaimmillaan 1000 kertaa nopeampia (työpöytäprosessoreissa 50 Gt/s, uusimmissa näytönohjaimissa 700 Gt/s). Mikrofonin äänisignaalin siirto ja kevyt prosessointi vaatii siis noin miljoonasosan nykyaikaisen tietokoneen laskentakapasiteetista.

Jos haluat esimerkkikoodia äänen kaappaamista varten, ChatGPT, Claude, Gemini ja vastaavat tekoälymallit osaavat opastaa alusta alkaen. Esimerkiksi simppeli C-ohjelma äänen tallentamiseen ALSA-rajapinnan kautta voisi näyttää seuraavalta:

Prompti:
Lainaus
Kirjoita C-kielinen ohjelma äänen kaappaamiseen muistipuskuriin Linuxissa. Toteuta komentorivivalitsin, jolla asetetaan kaapattavan äänen pituus sekunteina. Käytä lähdekoodissa englanninkielisiä tekstejä ja kommentteja.

Tekoälyn kirjoittama koodi capture.c:
Koodia: [Valitse]
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

#define SAMPLE_RATE 44100
#define CHANNELS 1
#define FORMAT SND_PCM_FORMAT_S16_LE

int main(int argc, char *argv[]) {
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    int err;

    // Default capture time = 1 second
    int seconds = 1;

    // Parse command-line argument
    if (argc > 1) {
        seconds = atoi(argv[1]);
        if (seconds <= 0) {
            fprintf(stderr, "Invalid duration: %s\n", argv[1]);
            return 1;
        }
    }

    printf("Capturing %d second(s) of audio...\n", seconds);

    // Open default capture device
    if ((err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
        fprintf(stderr, "Unable to open PCM device: %s\n", snd_strerror(err));
        return 1;
    }

    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_any(handle, params);

    snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(handle, params, FORMAT);
    snd_pcm_hw_params_set_channels(handle, params, CHANNELS);
    snd_pcm_hw_params_set_rate(handle, params, SAMPLE_RATE, 0);

    if ((err = snd_pcm_hw_params(handle, params)) < 0) {
        fprintf(stderr, "Unable to set HW params: %s\n", snd_strerror(err));
        snd_pcm_close(handle);
        return 1;
    }

    // Calculate total samples & buffer size
    size_t bytes_per_sample = 2; // S16_LE = 2 bytes
    size_t total_samples = (size_t)SAMPLE_RATE * CHANNELS * seconds;
    size_t buffer_size = total_samples * bytes_per_sample;

    unsigned char *buffer = malloc(buffer_size);
    if (!buffer) {
        fprintf(stderr, "Memory allocation failed\n");
        snd_pcm_close(handle);
        return 1;
    }

    size_t frames_to_read = SAMPLE_RATE * seconds;

    // Capture audio
    ssize_t frames_read = snd_pcm_readi(handle, buffer, frames_to_read);
    if (frames_read < 0) {
        fprintf(stderr, "Read error: %s\n", snd_strerror(frames_read));
        snd_pcm_close(handle);
        free(buffer);
        return 1;
    }

    printf("Captured %zd frames (%zu bytes) into memory.\n",
           frames_read, buffer_size);

    snd_pcm_close(handle);
    free(buffer);

    return 0;
}

Asenna ALSA:n headerit eli libasound2-dev:
Koodia: [Valitse]
sudo apt install libasound2-dev
Käännä:
Koodia: [Valitse]
gcc capture.c -lasound -o capture
Suorita:
Koodia: [Valitse]
./capture 5

Snufkin

  • Käyttäjä
  • Viestejä: 773
    • Profiili
Vs: Mikrofonin syöte c++ -taulukkoon
« Vastaus #2 : 21.11.25 - klo:21.10 »
En osaa sano asian digitaalisesta puolesta mitään, mutta jos tarve tallentaa vain puhetta, niin siihen riittää varmaan alle 10% tuosta CD-äänen tallennuksesta. Analogisissa puhelimissa taisi olla noin 3kHz taajuusalue käytössä. Jos ääni vielä melko tasaista voimakkuudeltaan, voisi riittää pienempi bittisyvyyskin.



Xubuntu 22.04 LTS, Fujitsu Lifebook E754