Tekoälyn käyttö oli hyvä vihje. Se kirjoittaakin nopeasti ohjelmia pyydettäessä
On Ubuntu 24.04 with the libasound2-dev package, write a c++ program that reads a sound sample of 5 seconds from the laptop microphone and stores in a buffer as 16 bit values from a single channel and then outputs the sample from the buffer via the laptop speakers.
Ylllä olevan pyynnön tuloksena saatu ohjelma kääntyy ilman varoituksia, mutta ei näytä tekevän yhtään mitään. Lisäsin sinne yhden tulostusrivinkin tarkistusta varten, mutta sekään ei tulostu.
En valitettavasti vielä ymmärrä äänenkäsittelystä niin paljon, että voisin arvioida, voisiko ohjelman kohtuutyöllä saada toimimaan.
#include <iostream>
#include <vector>
#include <alsa/asoundlib.h>
int main() {
const unsigned int sample_rate = 44100;
const unsigned int seconds = 5;
const unsigned int channels = 1;
const snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
const snd_pcm_uframes_t total_frames = sample_rate * seconds;
const snd_pcm_uframes_t period_size = 1024; // frames per read/write
std::vector<int16_t> buffer(total_frames * channels);
int rc;
snd_pcm_t* capture_handle = nullptr;
snd_pcm_t* playback_handle = nullptr;
snd_pcm_hw_params_t* params = nullptr;
// --------- Open and configure capture (microphone) ----------
rc = snd_pcm_open(&capture_handle, "default",
SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
std::cerr << "Unable to open capture device: "
<< snd_strerror(rc) << std::endl;
return 1;
}
snd_pcm_hw_params_malloc(¶ms);
snd_pcm_hw_params_any(capture_handle, params);
snd_pcm_hw_params_set_access(capture_handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(capture_handle, params, format);
snd_pcm_hw_params_set_channels(capture_handle, params, channels);
unsigned int rate = sample_rate;
snd_pcm_hw_params_set_rate_near(capture_handle, params, &rate, nullptr);
snd_pcm_uframes_t psize = period_size;
snd_pcm_hw_params_set_period_size_near(capture_handle, params, &psize, nullptr);
rc = snd_pcm_hw_params(capture_handle, params);
if (rc < 0) {
std::cerr << "Unable to set capture HW params: "
<< snd_strerror(rc) << std::endl;
snd_pcm_hw_params_free(params);
snd_pcm_close(capture_handle);
return 1;
}
snd_pcm_hw_params_free(params);
// --------- Capture into buffer ----------
{
snd_pcm_uframes_t frames_captured = 0;
while (frames_captured < total_frames) {
snd_pcm_uframes_t frames_to_read =
std::min(psize, total_frames - frames_captured);
rc = snd_pcm_readi(capture_handle,
buffer.data() + frames_captured * channels,
frames_to_read);
if (rc == -EPIPE) {
// Overrun
snd_pcm_prepare(capture_handle);
continue;
} else if (rc < 0) {
std::cerr << "Error reading from capture device: "
<< snd_strerror(rc) << std::endl;
break;
} else {
frames_captured += rc;
}
}
}
snd_pcm_drain(capture_handle);
snd_pcm_close(capture_handle);
std::cout << "näyte luettu:" << rc << std::endl;
// --------- Open and configure playback (speakers) ----------
rc = snd_pcm_open(&playback_handle, "default",
SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
std::cerr << "Unable to open playback device: "
<< snd_strerror(rc) << std::endl;
return 1;
}
snd_pcm_hw_params_malloc(¶ms);
snd_pcm_hw_params_any(playback_handle, params);
snd_pcm_hw_params_set_access(playback_handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(playback_handle, params, format);
snd_pcm_hw_params_set_channels(playback_handle, params, channels);
rate = sample_rate;
snd_pcm_hw_params_set_rate_near(playback_handle, params, &rate, nullptr);
psize = period_size;
snd_pcm_hw_params_set_period_size_near(playback_handle, params, &psize, nullptr);
rc = snd_pcm_hw_params(playback_handle, params);
if (rc < 0) {
std::cerr << "Unable to set playback HW params: "
<< snd_strerror(rc) << std::endl;
snd_pcm_hw_params_free(params);
snd_pcm_close(playback_handle);
return 1;
}
snd_pcm_hw_params_free(params);
// --------- Play back from buffer ----------
{
snd_pcm_uframes_t frames_written = 0;
while (frames_written < total_frames) {
snd_pcm_uframes_t frames_to_write =
std::min(psize, total_frames - frames_written);
rc = snd_pcm_writei(playback_handle,
buffer.data() + frames_written * channels,
frames_to_write);
if (rc == -EPIPE) {
// Underrun
snd_pcm_prepare(playback_handle);
continue;
} else if (rc < 0) {
std::cerr << "Error writing to playback device: "
<< snd_strerror(rc) << std::endl;
break;
} else {
frames_written += rc;
}
}
}
snd_pcm_drain(playback_handle);
snd_pcm_close(playback_handle);
return 0;
}
/*
g++ play_after_01.cpp -o play_after_01 -lasound
./play_after_01
*/
Muokk.
Muokkasin vähän vanhaa otsikkoa, ehkä olisi pitänyt laittaa uusi aihe, mutta toiminnan tarkistamiseksi se ääni olisi kätevää saada myös ulos koneesta. Tavote olisi siis saada ääni taullukkoon ja sieltä ulos kaiuttimelle tässä vaiheessa.