|
ALSA AUDIO
PROGRAMMING
Bagian
ini akan memperkenalkan bagaimana memprogram output sampel
audio pada Linux dengan menggunakan driver ALSA (Advance Linux
Sound Architecture). Informasi lengkap mengenai alsa dapat
diperoleh pada website mereka di www.alsa-project.org.
Sebelum
melakukan pembuatan program, pastikan bahwa output audio pada
komputer anda dapat bekerja dengan baik. Hal ini untuk
menghindari stres berlebihan, karena penulis pernah mengira ada
program yang salah, akan tetapi ternyata komputer penulis yang
tidak dapat "berbicara" :(.
Biasanya
setelah modul ALSA di muat, semua kanal volume dalam keadaan
mute (tidak aktif). Untuk tetap mengaktifkan volume output,
gunakan saja mixer.
Pemrograman
driver ALSA dilakukan dengan menggunakan fungsi-fungsi pustaka
yang berhubungan langsung dengan driver pada kernel (dalam
istilah kernel disebut dengan modul). Penggunaan modul-modul
ini menyebabkan program ALSA menjadi lebih mudah
dikustomisasikan.
Perlu
diperhatikan bahwa selama proses kompilasi dilakukan, pustaka
yang memang dibutuhkan harus dispesifikasikan dan path yang
berhubungan dengan pustaka. Biasanya path juga harus
didefinisikan karena tidak menggunakan path default.
Program
berikut dibawah diambil dari dokumentasi ALSA yang biasanya
juga dapat ditemukan pada direktori doc pada /usr/share/doc.
Program tersebut paling utama digunakan untuk melakukan
inisialisasi antarmuka pcm ALSA. Fungsi open pada antarmuka pcm
digunakan untuk mengaktifkanbentuk keluaran pada waktu fungsi
close dipanggil untuk menutup antarmuka pcm. Tiap-tiap bagian
pada fungsi open dan close terdiri atas section-nya
masing-masing.
Section
open dilakukan oleh fungsi snd_pcm_open.
#include
<stdio.h>
#include
<stdlib.h>
#include
<sys/asoundlib.h>
int
card = 0;
int
device = 0;
void*
handle;
...
int
err;
if
( (err = snd_pcm_open( &handle, card, device,
SND_PCM_OPEN_PLAYBACK
)) < 0 ) {
fprintf(
stderr,
"open
failed: %s\n", snd_strerror( err ) );
return
-1;
}
...
Jika
pemanggilan pada snd_pcm_open dapat dilakukan, maka fungsi
tersebut sekaligus menangani antarmuka pcm yang berupa void
pointer.
Nilai
0 yang diberikan pada card dan device menyebabkan soundcard
dapat bekerja dikarenakan fungsi pekerjaannya ditangani secara
virtual. Suara yang keluar dari output device dikerjakan oleh
pemanggilan fungsi snd_pcm_playback_format. Parameter yang
digunakan pada fungsi ini merupakan pointer ke struktur
snd_pcm_format dan penanganannya kemudian diserahkan kembali
pada fungsi pcm interface pada waktu proses open dilakukan.
snd_pcm_format_t
format;
format.format
= SND_PCM_SFMT_U8;
format.rate
= 22050;
format.channels
= 2;
if
( (err = snd_pcm_playback_format( handle,
&format
)) < 0 ) {
fprintf(
stderr, "format setup failed: %s\n",
snd_strerror(
err ) );
return
-1;
}
Nilai
yang mungkin untuk settiap field format adalah:
SND_PCM_SFMT_MU_LAW
SND_PCM_SFMT_A_LAW
SND_PCM_SFMT_IMA_ADPCM
SND_PCM_SFMT_U8
SND_PCM_SFMT_S16_LE
SND_PCM_SFMT_S16_BE
SND_PCM_SFMT_S8
SND_PCM_SFMT_U16_LE
SND_PCM_SFMT_U16_BE
SND_PCM_SFMT_MPEG
SND_PCM_SFMT_GSM
Berikut
adalah contoh lengkap program untuk mengeluarkan suara pada
driver ALSA. Program ini memiliki kemiripan dengan contoh pada
OSS/lite. OSS/Lite pertama kali melakukan generate suara selama
1 detik pada kanal suara sebelah kiri dan kemudian diikuti
dengan suara 1 detik pada sebelah kanan. Setelah itu program
akan diterminasi atau dihentikan.
#include
<stdio.h>
#include
<stdlib.h>
#include
<sys/asoundlib.h>
unsigned
char* data;
int
card = 0;
int
device = 0;
void*
handle;
void
ExitProc() {
snd_pcm_close(
handle );
}
int
main() {
int
i, err;
unsigned
char* ptr;
unsigned
char v = 128;
snd_pcm_format_t
format;
if
( (err = snd_pcm_open( &handle, card, device,
SND_PCM_OPEN_PLAYBACK
)) < 0 ) {
fprintf(
stderr,
"open
failed: %s\n", snd_strerror( err ) );
return
-1;
}
if
( atexit( ExitProc ) == -1 ) {
perror("atexit");
ExitProc();
return
-1;
}
format.format
= SND_PCM_SFMT_U8;
format.rate
= 22050;
format.channels
= 2;
if
( (err = snd_pcm_playback_format( handle,
&format
)) < 0 ) {
fprintf(
stderr, "format setup failed: %s\n",
snd_strerror(
err ) );
return
-1;
}
//
two seconds two channels
data
= malloc(22050*2*2L);
ptr
= data;
for
(i = 0; i < 22050; ++i) {
*ptr++
= v++; // set left channel
*ptr++
= 128; // right silence
}
for
(i = 22050; i < 44100; ++i) {
*ptr++
= 128;
*ptr++
= v++;
}
snd_pcm_write(
handle, data, 22050 * 4L );
return
0;
}
|