Skip to content

Latest commit

ย 

History

History
212 lines (165 loc) ยท 7.01 KB

ALSA_LINUX.md

File metadata and controls

212 lines (165 loc) ยท 7.01 KB

Linux ๊ธฐ๋ฐ˜์˜ ์˜ค๋””์˜ค ์ œ์–ด

Android ์˜ค๋””์˜ค์•„ํ‚คํ…์ฒ˜ ์š”์•ฝ

Android ํ”Œ๋žซํผ์—์„œ ์˜ค๋””์˜ค ์ฝ”๋ฑ์„ ์ œ์–ดํ•˜๋Š” ๋ฐ๋Š” ALSA(Advanced Linux Sound Architecture) ๊ธฐ๋ฐ˜์˜ tinyalsa ๋˜๋Š” alsalib์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ , ์ด๋Š” Android์˜ Audio HAL(Hardware Abstration Layer) ๊ตฌํ˜„์— ํฌํ•จ๋จ.

+-------------------------------+
|           App Layer          |
+-------------------------------+
|       Audio Framework         |
|  (AudioFlinger, AudioPolicy) |
+-------------------------------+
|       Audio HAL Interface     |
|       (audio_hw.c ๋“ฑ)        |
+-------------------------------+
|        tinyalsa / alsa-lib    |
+-------------------------------+
|        ALSA kernel driver     |
+-------------------------------+
|     I2S, I2C ๋“ฑ H/W ์ธํ„ฐํŽ˜์ด์Šค |
+-------------------------------+

๐Ÿ”ง tinyalsa์˜ ์—ญํ• 

  • tinyalsa๋Š” AOSP์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ๋Ÿ‰ ALSA ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, Android์˜ ์˜ค๋””์˜ค HAL ๋ ˆ๋ฒจ์—์„œ ์ง์ ‘ ALSA ๋””๋ฐ”์ด์Šค๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ ๋ชฉ์ :
    • PCM ์ถœ๋ ฅ (Playback) ๋ฐ ์ž…๋ ฅ (Capture)
    • Mixer control (๋ณผ๋ฅจ, Mux, Mute ๋“ฑ)
    • Routing control

audio_hw.c ๋˜๋Š” xxx_audio_hw.c ๊ฐ™์€ HAL ํŒŒ์ผ ๋‚ด์—์„œ tinyalsa API๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ PCM ์žฅ์น˜๋ฅผ open/read/write/close ํ•จ.

โš™๏ธ ์ฐธ๊ณ : Tinyalsa vs alsa-lib

ํ•ญ๋ชฉ tinyalsa alsa-lib
์šฉ๋„ Android HAL์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ ์ผ๋ฐ˜ Linux ๋ฐ์Šคํฌํƒ‘, ์„œ๋ฒ„ ๋“ฑ
ํŠน์ง• ๊ฒฝ๋Ÿ‰, AOSP์— ํฌํ•จ ๋ณต์žกํ•˜๊ณ  ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ์ œ๊ณต
API ๋‹จ์ˆœ: pcm_open, mixer_get ๋ณต์žก: snd_pcm_open, snd_ctl_*
AOSP ํฌํ•จ ์—ฌ๋ถ€ ํฌํ•จ (external/tinyalsa) ๋ฏธํฌํ•จ (๋ณ„๋„ ํฌํŒ… ํ•„์š”)




alsa-lib๊ฐœ์š”

Linux ํ”Œ๋žซํผ์—์„œ๋Š” ์˜ค๋””์˜ค ์ œ์–ด ์‹œ ์ผ๋ฐ˜์ ์œผ๋กœ alsa-lib ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์ด๋Š” ALSA ์ปค๋„ ๋“œ๋ผ์ด๋ฒ„์™€ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„(user-space) ๊ฐ„์˜ ์ธํ„ฐํŽ˜์ด์Šค ์—ญํ• ์„ ํ•จ.

โœ… 1. alsa-lib ๊ฐœ์š”

  • ์ •์‹ ๋ช…์นญ: Advanced Linux Sound Architecture library
  • ์†Œ์Šค ์œ„์น˜: https://github.com/alsa-project/alsa-lib
  • ์ฃผ์š” ํŒŒ์ผ: libasound.so, alsa/asoundlib.h
  • ์—ญํ• :
    • snd_pcm_* (PCM ๋””๋ฐ”์ด์Šค ์ œ์–ด)
    • snd_mixer_* (Mixer ์ œ์–ด)
    • snd_ctl_* (์ปจํŠธ๋กค ์ œ์–ด)
    • ~/.asoundrc, /etc/asound.conf ๋“ฑ ๊ตฌ์„ฑ ํŒŒ์ผ ๋กœ๋”ฉ




Linux ํ”Œ๋žซํผ ์˜ค๋””์˜ค์ œ์–ด

โœ… Linux ๊ธฐ๋ฐ˜์˜ ์˜ค๋””์˜ค ์Šคํƒ ๊ฐœ์š”

+-------------------------------+
|      Application Layer        |
|   (e.g., aplay, GStreamer)    |
+-------------------------------+
|       Audio Libraries         |
| alsa-lib, PulseAudio, PipeWire|
+-------------------------------+
|      ALSA Kernel Interface    |
|   (soundcore, snd_pcm, etc.)  |
+-------------------------------+
|        H/W Driver Layer       |
|     (I2S, Codec Driver ๋“ฑ)    |
+-------------------------------+

๐Ÿ”ง ์ฃผ์š” ์˜ค๋””์˜ค ์ œ์–ด ์†”๋ฃจ์…˜ 5๊ฐ€์ง€

  1. alsa-lib (Advanced Linux Sound Architecture Library)
  • ํ‘œ์ค€ Linux ์˜ค๋””์˜ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ. ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์—์„œ ALSA ๋””๋ฐ”์ด์Šค๋ฅผ ์ œ์–ด.
  • ์‚ฌ์šฉ ๋ฐฉ์‹์€ ๋ณต์žกํ•˜์ง€๋งŒ, ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณต.
  • ๊ฐœ๋ฐœ์ž ์ˆ˜์ค€์˜ low-level control ๊ฐ€๋Šฅ.
  • API ์˜ˆ: snd_pcm_open, snd_pcm_writei, snd_ctl_*
  1. asound.conf / .asoundrc
  • ALSA ์žฅ์น˜์˜ ๋ผ์šฐํŒ…, ๋ฏน์‹ฑ, ๋ณ€ํ™˜์„ ๊ตฌ์„ฑํ•˜๋Š” ์„ค์ • ํŒŒ์ผ.
  • ์‹œ์Šคํ…œ ์ˆ˜์ค€ ๋˜๋Š” ์‚ฌ์šฉ์ž ์ˆ˜์ค€ ์˜ค๋””์˜ค ๋ผ์šฐํŒ… ์„ค์ • ๊ฐ€๋Šฅ.
  • ์˜ˆ: ํŠน์ • PCM์„ default๋กœ ์ง€์ •, dmix ์‚ฌ์šฉ ์„ค์ • ๋“ฑ
    1. amixer / alsamixer (CLI ๊ธฐ๋ฐ˜ ๋ฏน์„œ ๋„๊ตฌ)
  • ALSA mixer ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ์–ดํ•˜๋Š” CLI ๋„๊ตฌ
  • ๋ณผ๋ฅจ ์ œ์–ด, mux ์„ ํƒ, ๋งˆ์ดํฌ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™” ๋“ฑ ์ˆ˜ํ–‰
  • amixer, alsamixer ๋ชจ๋‘ mixer control์„ ํŽธํ•˜๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ
  1. PulseAudio (์ค‘๊ฐ„ ๋ ˆ์ด์–ด ์‚ฌ์šด๋“œ ์„œ๋ฒ„)
  • ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌ ์•ฑ์—์„œ ๋™์‹œ์— ์˜ค๋””์˜ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์‚ฌ์šด๋“œ ์„œ๋ฒ„
  • ALSA ์œ„์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, ๋„คํŠธ์›Œํฌ ์˜ค๋””์˜ค ์ŠคํŠธ๋ฆฌ๋ฐ ๋“ฑ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ ์ œ๊ณต
  • ๋ฐ์Šคํฌํƒ‘ Linux์—์„œ๋Š” ๊ธฐ๋ณธ ๊ตฌ์„ฑ (ex: Ubuntu)
  1. PipeWire (์‹ ํ˜• ์‚ฌ์šด๋“œ/๋ฏธ๋””์–ด ์„œ๋ฒ„)
  • PulseAudio๋ฅผ ๋Œ€์ฒดํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœ์ ํŠธ
  • ์˜ค๋””์˜ค + ๋น„๋””์˜ค ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ฉ์ ์œผ๋กœ ๊ด€๋ฆฌ
  • ์ตœ์‹  GNOME ๊ธฐ๋ฐ˜ ๋ฐ์Šคํฌํƒ‘์—์„œ ๊ธฐ๋ณธ ์ฑ„ํƒ ์ค‘ (์˜ˆ: Ubuntu 22.04 ์ด์ƒ)

๐Ÿ”ง Embedded Linux์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์จ์•ผ ํ• ๊นŒ?

  • ๋ฆฌ์†Œ์Šค๊ฐ€ ์ ๋‹ค๋ฉด alsa-lib + amixer ๊ธฐ๋ฐ˜ ์ œ์–ด๋ฅผ ์„ ํ˜ธ
  • ์˜ค๋””์˜ค ์ฝ”๋ฑ ์ œ์–ด๋Š” Device Tree ๋˜๋Š” I2C ํ†ตํ•ด codec driver์—์„œ ๋‹ค๋ฃธ
  • ํ•„์š” ์‹œ UCM (Use Case Manager) ๋˜๋Š” ๊ฐ„๋‹จํ•œ ์ปค์Šคํ…€ Audio HAL ๊ตฌํ˜„ ๊ฐ€๋Šฅ




AK7755 ์˜ค๋””์˜ค ์ฝ”๋ฑ์„ Linux ALSA ํ™˜๊ฒฝ์—์„œ ์ œ์–ด ์˜ˆ์ œ

โœ… ์ „์ œ ์กฐ๊ฑด

  • AK7755๊ฐ€ I2C๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ , ๊ด€๋ จ ์ปค๋„ ๋“œ๋ผ์ด๋ฒ„(sound/soc/codecs/ak7755.c)๊ฐ€ ๋“ฑ๋ก.
  • device tree ๋˜๋Š” platform data๋ฅผ ํ†ตํ•ด ๋“ฑ๋ก๋œ ์ƒํƒœ
  • ALSA Mixer ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์ œ์–ด ๊ฐ€๋Šฅํ•œ ์ƒํƒœ
  • amixer, alsamixer ๋˜๋Š” C ์ฝ”๋“œ์—์„œ alsa-lib API๋กœ ์ปจํŠธ๋กค ๊ฐ€๋Šฅ

โœ… 1. amixer ๋˜๋Š” alsamixer๋ฅผ ํ†ตํ•œ ์ œ์–ด ์˜ˆ์‹œ AK7755 ๋“œ๋ผ์ด๋ฒ„๋Š” ALSA mixer control์— ์—ฌ๋Ÿฌ ์ปจํŠธ๋กค ๋…ธ๋“œ๋ฅผ ์ œ๊ณต.

# ์ „์ฒด Mixer ์ปจํŠธ๋กค ๋…ธ๋“œ ํ™•์ธ
amixer -c 0 scontrols

# ์˜ˆ์‹œ ์ถœ๋ ฅ:
# Simple mixer control 'AK7755 DAC Playback Volume',0
# Simple mixer control 'AK7755 ADC Capture Switch',0

# DAC ๋ณผ๋ฅจ ์ œ์–ด
amixer -c 0 sset 'AK7755 DAC Playback Volume' 80%

# ADC ๋งˆ์ดํฌ ์ž…๋ ฅ ํ™œ์„ฑํ™”
amixer -c 0 sset 'AK7755 ADC Capture Switch' on

โœ… 2. C ์ฝ”๋“œ ์˜ˆ์‹œ (alsa-lib ๊ธฐ๋ฐ˜)

#include <alsa/asoundlib.h>

int main() {
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *sid;

    const char *card = "default"; // ๋˜๋Š” hw:0
    const char *selem_name = "AK7755 DAC Playback Volume";

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, card);
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);

    snd_mixer_selem_id_malloc(&sid);
    snd_mixer_selem_id_set_index(sid, 0);
    snd_mixer_selem_id_set_name(sid, selem_name);

    elem = snd_mixer_find_selem(handle, sid);
    if (!elem) {
        printf("Control not found\n");
        return 1;
    }

    // ๋ณผ๋ฅจ 80% ์„ค์ • (range: 0~max)
    long minv, maxv;
    snd_mixer_selem_get_playback_volume_range(elem, &minv, &maxv);
    long set_vol = minv + (maxv - minv) * 0.8;
    snd_mixer_selem_set_playback_volume_all(elem, set_vol);

    snd_mixer_close(handle);
    snd_mixer_selem_id_free(sid);

    return 0;
}

โœ… 3. DAPM ์ œ์–ด๋„ ๊ฐ€๋Šฅ (Platform ์ธก) AK7755๋Š” **DAPM (Dynamic Audio Power Management)**์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋ฑ์ด๋ฏ€๋กœ, DAI ๋ผ์šฐํŒ…์„ ์กฐ์ •ํ•˜๋ฉด ์ž๋™์œผ๋กœ ํ•„์š”ํ•œ path๋ฅผ power on/off ํ•จ.

๋งŒ์•ฝ platform driver์—์„œ route๋ฅผ ์ง์ ‘ ์„ค์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:

static const struct snd_soc_dapm_route audio_routes[] = {
    {"Headphone", NULL, "AK7755 DAC"},
    {"AK7755 DAC", NULL, "Playback"},
    {"AK7755 ADC", NULL, "Mic Bias"},
    {"Capture", NULL, "AK7755 ADC"},
};