FSTWikiDiff for 1.1 alsa
Login:
Password:
Join
E D R S I H P RSS
FrontPage|FindPage|TitleIndex|RecentChanges

Difference between r1.1 and the current

@@ -10,8 +10,291 @@
ALSA의 공식 사이트는 다음과 같다.

[http://www.alsa-project.org/]
== 드라이버 개발을 위한 문서 ==
* Writing an ALSA Driver [http://www.alsa-project.org/~iwai/writing-an-alsa-driver/index.html HTML] [http://www.alsa-project.org/~iwai/writing-an-alsa-driver.pdf PDF]

== 드라이버 API == 
=== 자료 구조 === 
snd_card_t는 <sound/core.h>에 정의 되어 있다. 이는 strcut _snd_card 의 typedef형이다. 
{{{ 
struct _snd_card { 
char driver[16]; /* 드라이버 이름 */ 
char shortname[32]; /* 사운드 카드의 짧은 이름 */ 
char longname[80]; /* 사운드 카드의 이름 */ 
 
void *private_data; /* 사운드 카드에 대한 추가 정보 */ 
void (*private_free) (snd_card_t *card); /* 추가 정보을 위해 할당받은 자원 */ 
/* 반환을 위한 콜백 */ 
}}} 
/!\ 위 구조체의 필드는 위 명시된 내용 외에도 무수히 많다. 사용자가 꼭 알아야 하는 것들만 나열했다. 
=== snd_card_new === 
사운드 카드의 구조체를 할당 받는다. 
{{{#!vim c 
snd_card_t *snd_card_new(int idx, const char *xid, 
struct module *module, int extra_size) 
}}} 
 
||매개변수||설명|| 
||idx||카드의 인덱스(주소),0에서 (SNDRV_CARDS-1)|| 
||xid||카드 이름 (문자열)|| 
||module||locking을 소유한 상위 모듈|| 
||extra_size||사운드카드 구조체 이후 추가 할당받을 메모리 크기|| 
 
성공하면 snd_card_t형의 포인터를 반환하고 실패하면 NULL을 반환한다. 
 
{{{#!vim c 
snd_card_t *card; 
 
card = snd_card_new(-1, id, THIS_MODULE, sizeof(foo_bar)); 
if (card == NULL) 
return -ENOMEM; 
}}} 
=== snd_card_register === 
사운드 카드를 등록한다. 
 
{{{#!vim c 
int snd_card_register(snd_card_t *card) 
}}} 
 
성공하면 0을 반환하고, 실패하면 0이 아닌 값을 반환한다. 
 
관련함수: snd_card_free 
=== snd_card_free === 
사운드카드 구조체의 자원을 반환한다. 
 
{{{#!vim c 
int snd_card_free(snd_card_t *card) 
}}} 
 
성공하면 0을 반환하고, 실패하면 0이 아닌 값을 반환한다. 
 
관련함수: snd_card_new, snd_card_register 
=== 전원 관리 === 
전원 관리 함수는 CONFIG_PM 이 정의된 경우에만 유효 하도록 작성한다. 
{{{#!vim c 
#ifdef CONFIG_PM 
static int snd_foo_suspend(...) 
... 
#endif 
}}} 
 
snd_card_set_pm_callback() 
snd_power_change_state() 
snd_pcm_suspend_all() 
 
||전원 상태 매크로||설명|| 
||SNDRV_CTRL_POWER_D0||Full On 상태|| 
||SNDRV_CTRL_POWER_D1||일부만 On 상태|| 
||SNDRV_CTRL_POWER_D2||일부만 On 상태|| 
||SNDRV_CTRL_POWER_D3||Off 상태|| 
||SNDRV_CTRL_POWER_D3hot||전원은 공급되지만 Off 상태|| 
||SNDRV_CTRL_POWER_D3cold||전원 공급도 없는 Off 상태|| 
 
==== snd_card_set_pm_callback ==== 
전원 관리를 위한 콜백을 등록한다. 
 
{{{#!vim c 
int snd_card_set_pm_callback(snd_card_t *card, 
int (*suspend)(snd_card_t *, pm_message_t), 
int (*resume)(snd_card_t *), 
void *private_data) 
}}} 
 
||필드||설명|| 
||card||사운드카드 구조체|| 
||suspend||절전 모드 진입시 호출되는 콜백|| 
||resume||절전 모드 해제시 호출되는 콜백|| 
||private_data||콜백에 넘길 매개 변수의 포인터|| 
 
항상 0을 반환한다. 
 
이 함수는 매개변수 card의 필드 중 pm_suspend, pm_resume, pm_private_data 를 넘겨주는 매개 변수의 값으로 설정한다. 
 
{{{#!vim c 
snd_card_set_pm_callback(card, snd_foo_suspend, snd_foo_resume, foo); 
}}} 
 
==== snd_power_change_state ==== 
==== snd_pcm_suspend_all ==== 
=== PCM === 
==== 자료 구조 ==== 
==== PCM 연산 ==== 
다음의 자료형은 <sound/pcm.h> 파일에 정의되어 있다. 
 
{{{#!vim c 
typedef struct _snd_pcm_ops { 
int (*open)(snd_pcm_substream_t *substream); 
int (*close)(snd_pcm_substream_t *substream); 
int (*ioctl)(snd_pcm_substream_t *substream, unsigned int cmd, void *arg); 
int (*hw_params)(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params); 
int (*hw_free)(snd_pcm_substream_t *substream); 
int (*prepare)(snd_pcm_substream_t *substream); 
int (*trigger)(snd_pcm_substream_t *substream, int cmd); 
snd_pcm_uframes_t (*pointer)(snd_pcm_substream_t *substream); 
int (*copy)(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos, 
void __user *buf, snd_pcm_ufreams_t count); 
struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset); 
int (*mmap)(snd_pcm_substream_t *substream, struct vm_area_struct *vma); 
int (*ack)(snd_pcm_substream_t *substream); 
} snd_pcm_ops_t; 
}}} 
 
||필드||설명|| 
||open|||| 
||close|||| 
||ioctl|||| 
||hw_parames|||| 
||hw_free|||| 
||prepare|||| 
||trigger|||| 
||pointer|||| 
===== open ===== 
어떤 스트림인지를 결정한다. 
 
함수 원형은 다음과 같다: 
{{{#!vim c 
static int xxx_open(snd_pcm_substream_t *substream) 
}}} 
===== close ===== 
===== ioctl ===== 
===== hw_params ===== 
===== hw_free ===== 
===== prepare ===== 
스트림의 처리 전에 초기값을 설정한다. 예를 들면, sample rate등이 있다. 
 
함수 원형은 다음과 같다: 
{{{#!vim c 
static int xxx_prepare(snd_pcm_substream_t *substream) 
}}} 
===== trigger ===== 
스트림의 중단 및 시작을 처리한다. 
 
함수 원형은 다음과 같다: 
{{{#!vim c 
static int xxx_trigger(snd_pcm_substream_t *substream, int cmd) 
}}} 
 
cmd는 <sound/pcm.h>에 정의된 매크로이다. 
||cmd||설명|| 
||SNDRV_PCM_TRIGGER_STOP||스트림을 종료한다.|| 
||SNDRV_PCM_TRIGGER_START||스트림을 시작한다.|| 
===== pointer ===== 
현 스트림의 위치를 가져온다. 
 
함수 원형은 다음과 같다: 
{{{#!vim c 
static snd_pcm_uframes_t xxx_pointer(snd_pcm_substream_t *substream) 
}}} 
==== snd_pcm_new ==== 
새로운 PCM 디바이스를 위한 자원을 할당받는다. 이러한 역할을 하는 함수가 snd_pcm_new 함수이다. 
 
함수의 원형은 다음과 같다: 
{{{#!vim c 
int snd_pcm_new(snd_card_t *card, char *id, int device, 
int playback_count, int capture_count, 
snd_pcm_t **rpcm) 
}}} 
 
||매개변수||설명|| 
||card||사운드 카드 데이터의 포인터|| 
||id||ID 문자열|| 
||device||장치 인덱스 (0부터 시작한다)|| 
||playback_count||재생할 때 스트림의 개수|| 
||capture_count||녹음할 때 스트림의 개수|| 
||rpcm||새 pcm 디바이스를 위한 자원을 저장하기 위한 포인터|| 
 
성공하면 0을 반환하고, 실패하면 음의 에러 코드 값을 반환한다. 
 
사용 예를 보면 다음과 같다: 
{{{#!vim c 
int err; 
snd_pcm_t *pcm; 
 
if ((err = snd_pcm_new(foo->card, "FOO ACM", device, 1, 1, &pcm)) < 0) 
return err; 
}}}  
==== snd_pcm_lib_preallocate_pages_for_all ==== 
스트림을 위한 연속된 메모리를 할당받기 위한 사전 작업을 처리한다.  
 
함수의 원형은 다음과 같다: 
{{{#!vim c 
int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm, int type, void *data, 
size_t size, size_t max) 
}}} 
 
||매개변수||설명|| 
||pcm||pcm 디바이스 포인터|| 
||type||SNDRV_DMA_TYPE_로 시작하는 DMA 타입|| 
||data||DMA 타입에 따른 데이터|| 
||size||사전 할당을 받아야 하는 메모리의 바이트 단위의 크기|| 
||max||허용하는 최대 메모리 크기|| 
 
data 인자에 사용할 수 있는 것들은 다음과 같다: 
||data||설명|| 
||snd_dma_pci_data()|||| 
||snd_dma_isa_data()|||| 
||snd_dma_sbus_data()|||| 
||snd_dma_continuous_data()|||| 
 
성공하면 0을 반환하고 실패하면 에러코드인 음수를 반환한다. 
 
type 필드에 사용할 수 있는 것들은 다음과 같다: 
||type||설명|| 
||SNDRV_DMA_TYPE_UNKNOWN||정의 되지 않은 타입|| 
||SNDRV_DMA_TYPE_CONTINUOUS||DMA가 아닌 연속된 메모리(가상메모리)|| 
||SNDRV_DMA_TYPE_DEV||디바이스를 위한 연속된 메모리(가상메모리/물리메모리)|| 
||SNDRV_DMA_TYPE_DEV_SG||디바이스를 위한 연속된 SG-버퍼|| 
||SNDRV_DMA_TYPE_SBUS||연속된 SBUS|| 
 
 
다음은 사용예이다:  
{{{#!vim c 
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINOUS, 
snd_dma_continues_data(GFP_KERNEL), 
128 * 1024, 128 * 1024); 
}}} 
==== snd_pcm_set_ops ==== 
PCM의 동작을 위한 연산 테이블을 등록한다. 
 
{{{#!vim c 
void snd_pcm_set_ops(snd_pcm_t *pcm, int direction, snd_pcm_ops_t *ops) 
}}} 
 
||direction||설명|| 
||SNDRV_PCM_STREAM_PLAYBACK|||| 
||SNDRV_PCM_STREAM_CAPTURE|||| 
=== MIXER === 
믹서는 사운드 카드를 제어하는 인터페이스이다. 여러 개의 제어기가 존재할 수 있다. 이들을 믹서에 추가하는 것은 snd_ctl_new함수가 처리한다. 
 
==== snd_ctl_new ==== 
믹서에 제어기를 등록한다. 
 
함수 원형은 다음과 같다: 
{{{#!vim c 
int snd_ctl_add(snd_card_t *card, snd_kcontrl_t *kcontrol) 
}}} 
 
성공하면 0을 반환하고, 실패하면 0이 아닌 에러코드를 반환한다. 
 
사용예는 다음과 같다: 
{{{#!vim c 
if ((err = snd_ctl_add(card, snd_ctl_new1(&xxx_contols[idx], chip))) < 0) 
return err; 
}}}  
==== snd_ctl_new1 ==== 
제어기에 대한 정보를 쉽게 생성시킬 수 있도록 도와주는 함수이다. 
 
함수의 원형은 다음과 같다: 
{{{#!vim c 
snd_kctonrol_t *snd_ctl_new1(const snd_kcontol_new_t *ncontrol, void *private_data) 
}}} 
 
사용예는 다음과 같다: 
{{{#!vim c 
if ((err = snd_ctl_add(card, snd_ctl_new1(&xxx_contols[idx], chip))) < 0) 
return err; 
}}}



ALSA #

-- 김도집 2005-08-23 13:41:42

Contents

1 ALSA
1.1 ALSA란?
1.2 드라이버 개발을 위한 문서
1.3 드라이버 API
1.3.1 자료 구조
1.3.2 snd_card_new
1.3.3 snd_card_register
1.3.4 snd_card_free
1.3.5 전원 관리
1.3.5.1 snd_card_set_pm_callback
1.3.5.2 snd_power_change_state
1.3.5.3 snd_pcm_suspend_all
1.3.6 PCM
1.3.6.1 자료 구조
1.3.6.2 PCM 연산
1.3.6.2.1 open
1.3.6.2.2 close
1.3.6.2.3 ioctl
1.3.6.2.4 hw_params
1.3.6.2.5 hw_free
1.3.6.2.6 prepare
1.3.6.2.7 trigger
1.3.6.2.8 pointer
1.3.6.3 snd_pcm_new
1.3.6.4 snd_pcm_lib_preallocate_pages_for_all
1.3.6.5 snd_pcm_set_ops
1.3.7 MIXER
1.3.7.1 snd_ctl_new
1.3.7.2 snd_ctl_new1

1.1 ALSA란? #

ALSA는 Advanced Linux Sound Architecture의 약어이다. 이는 리눅스 운영체제에서 오디오와 미디 기능을 제공하기 위한 아키텍처이다.


ALSA의 공식 사이트는 다음과 같다.

[http]http://www.alsa-project.org/

1.2 드라이버 개발을 위한 문서 #

1.3 드라이버 API #

1.3.1 자료 구조 #

snd_card_t는 <sound/core.h>에 정의 되어 있다. 이는 strcut _snd_card 의 typedef형이다.
struct _snd_card {
  char driver[16];     /* 드라이버 이름 */
  char shortname[32];  /* 사운드 카드의 짧은 이름 */
  char longname[80];   /* 사운드 카드의 이름 */

  void *private_data;  /* 사운드 카드에 대한 추가 정보 */
  void (*private_free) (snd_card_t *card);  /* 추가 정보을 위해 할당받은 자원 */
                                            /* 반환을 위한 콜백 */
/!\ 위 구조체의 필드는 위 명시된 내용 외에도 무수히 많다. 사용자가 꼭 알아야 하는 것들만 나열했다.

1.3.2 snd_card_new #

사운드 카드의 구조체를 할당 받는다.
snd_card_t *snd_card_new(int idx, const char *xid,
                         struct module *module, int extra_size)

매개변수설명
idx카드의 인덱스(주소),0에서 (SNDRV_CARDS-1)
xid카드 이름 (문자열)
modulelocking을 소유한 상위 모듈
extra_size사운드카드 구조체 이후 추가 할당받을 메모리 크기

성공하면 snd_card_t형의 포인터를 반환하고 실패하면 NULL을 반환한다.

snd_card_t *card;

card = snd_card_new(-1, id, THIS_MODULE, sizeof(foo_bar));
if (card == NULL)
  return -ENOMEM;

1.3.3 snd_card_register #

사운드 카드를 등록한다.

int snd_card_register(snd_card_t *card)

성공하면 0을 반환하고, 실패하면 0이 아닌 값을 반환한다.

관련함수: snd_card_free

1.3.4 snd_card_free #

사운드카드 구조체의 자원을 반환한다.

int snd_card_free(snd_card_t *card)

성공하면 0을 반환하고, 실패하면 0이 아닌 값을 반환한다.

관련함수: snd_card_new, snd_card_register

1.3.5 전원 관리 #

전원 관리 함수는 CONFIG_PM 이 정의된 경우에만 유효 하도록 작성한다.
#ifdef CONFIG_PM
static int snd_foo_suspend(...)
{
...
}
#endif

snd_card_set_pm_callback() snd_power_change_state() snd_pcm_suspend_all()

전원 상태 매크로설명
SNDRV_CTRL_POWER_D0Full On 상태
SNDRV_CTRL_POWER_D1일부만 On 상태
SNDRV_CTRL_POWER_D2일부만 On 상태
SNDRV_CTRL_POWER_D3Off 상태
SNDRV_CTRL_POWER_D3hot전원은 공급되지만 Off 상태
SNDRV_CTRL_POWER_D3cold전원 공급도 없는 Off 상태

1.3.5.1 snd_card_set_pm_callback #

전원 관리를 위한 콜백을 등록한다.

int snd_card_set_pm_callback(snd_card_t *card,
                             int (*suspend)(snd_card_t *, pm_message_t),
                             int (*resume)(snd_card_t *),
                             void *private_data)

필드설명
card사운드카드 구조체
suspend절전 모드 진입시 호출되는 콜백
resume절전 모드 해제시 호출되는 콜백
private_data콜백에 넘길 매개 변수의 포인터

항상 0을 반환한다.

이 함수는 매개변수 card의 필드 중 pm_suspend, pm_resume, pm_private_data 를 넘겨주는 매개 변수의 값으로 설정한다.

snd_card_set_pm_callback(card, snd_foo_suspend, snd_foo_resume, foo);

1.3.5.2 snd_power_change_state #

1.3.5.3 snd_pcm_suspend_all #

1.3.6 PCM #

1.3.6.1 자료 구조 #

1.3.6.2 PCM 연산 #

다음의 자료형은 <sound/pcm.h> 파일에 정의되어 있다.

typedef struct _snd_pcm_ops {
  int (*open)(snd_pcm_substream_t *substream);
  int (*close)(snd_pcm_substream_t *substream);
  int (*ioctl)(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
  int (*hw_params)(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
  int (*hw_free)(snd_pcm_substream_t *substream);
  int (*prepare)(snd_pcm_substream_t *substream);
  int (*trigger)(snd_pcm_substream_t *substream, int cmd);
  snd_pcm_uframes_t (*pointer)(snd_pcm_substream_t *substream);
  int (*copy)(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos,
              void __user *buf, snd_pcm_ufreams_t count);
  struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
  int (*mmap)(snd_pcm_substream_t *substream, struct vm_area_struct *vma);
  int (*ack)(snd_pcm_substream_t *substream);
} snd_pcm_ops_t;

필드설명
open
close
ioctl
hw_parames
hw_free
prepare
trigger
pointer
1.3.6.2.1 open #
어떤 스트림인지를 결정한다.

함수 원형은 다음과 같다:
static int xxx_open(snd_pcm_substream_t *substream)
1.3.6.2.2 close #
1.3.6.2.3 ioctl #
1.3.6.2.4 hw_params #
1.3.6.2.5 hw_free #
1.3.6.2.6 prepare #
스트림의 처리 전에 초기값을 설정한다. 예를 들면, sample rate등이 있다.

함수 원형은 다음과 같다:
static int xxx_prepare(snd_pcm_substream_t *substream)
1.3.6.2.7 trigger #
스트림의 중단 및 시작을 처리한다.

함수 원형은 다음과 같다:
static int xxx_trigger(snd_pcm_substream_t *substream, int cmd)

cmd는 <sound/pcm.h>에 정의된 매크로이다.
cmd설명
SNDRV_PCM_TRIGGER_STOP스트림을 종료한다.
SNDRV_PCM_TRIGGER_START스트림을 시작한다.
1.3.6.2.8 pointer #
현 스트림의 위치를 가져온다.

함수 원형은 다음과 같다:
static snd_pcm_uframes_t xxx_pointer(snd_pcm_substream_t *substream)

1.3.6.3 snd_pcm_new #

새로운 PCM 디바이스를 위한 자원을 할당받는다. 이러한 역할을 하는 함수가 snd_pcm_new 함수이다.

함수의 원형은 다음과 같다:
int snd_pcm_new(snd_card_t *card, char *id, int device,
                int playback_count, int capture_count,
                snd_pcm_t **rpcm)

매개변수설명
card사운드 카드 데이터의 포인터
idID 문자열
device장치 인덱스 (0부터 시작한다)
playback_count재생할 때 스트림의 개수
capture_count녹음할 때 스트림의 개수
rpcm새 pcm 디바이스를 위한 자원을 저장하기 위한 포인터

성공하면 0을 반환하고, 실패하면 음의 에러 코드 값을 반환한다.

사용 예를 보면 다음과 같다:
int err;
snd_pcm_t *pcm;

if ((err = snd_pcm_new(foo->card, "FOO ACM", device, 1, 1, &pcm)) < 0)
  return err;
}

1.3.6.4 snd_pcm_lib_preallocate_pages_for_all #

스트림을 위한 연속된 메모리를 할당받기 위한 사전 작업을 처리한다.

함수의 원형은 다음과 같다:
int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm, int type, void *data,
                                          size_t size, size_t max)

매개변수설명
pcmpcm 디바이스 포인터
typeSNDRV_DMA_TYPE_로 시작하는 DMA 타입
dataDMA 타입에 따른 데이터
size사전 할당을 받아야 하는 메모리의 바이트 단위의 크기
max허용하는 최대 메모리 크기

data 인자에 사용할 수 있는 것들은 다음과 같다:
data설명
snd_dma_pci_data()
snd_dma_isa_data()
snd_dma_sbus_data()
snd_dma_continuous_data()

성공하면 0을 반환하고 실패하면 에러코드인 음수를 반환한다.

type 필드에 사용할 수 있는 것들은 다음과 같다:
type설명
SNDRV_DMA_TYPE_UNKNOWN정의 되지 않은 타입
SNDRV_DMA_TYPE_CONTINUOUSDMA가 아닌 연속된 메모리(가상메모리)
SNDRV_DMA_TYPE_DEV디바이스를 위한 연속된 메모리(가상메모리/물리메모리)
SNDRV_DMA_TYPE_DEV_SG디바이스를 위한 연속된 SG-버퍼
SNDRV_DMA_TYPE_SBUS연속된 SBUS


다음은 사용예이다:
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINOUS,
                                      snd_dma_continues_data(GFP_KERNEL),
                                      128 * 1024, 128 * 1024);

1.3.6.5 snd_pcm_set_ops #

PCM의 동작을 위한 연산 테이블을 등록한다.

void snd_pcm_set_ops(snd_pcm_t *pcm, int direction, snd_pcm_ops_t *ops)

direction설명
SNDRV_PCM_STREAM_PLAYBACK
SNDRV_PCM_STREAM_CAPTURE

1.3.7 MIXER #

믹서는 사운드 카드를 제어하는 인터페이스이다. 여러 개의 제어기가 존재할 수 있다. 이들을 믹서에 추가하는 것은 snd_ctl_new함수가 처리한다.

1.3.7.1 snd_ctl_new #

믹서에 제어기를 등록한다.

함수 원형은 다음과 같다:
int snd_ctl_add(snd_card_t *card, snd_kcontrl_t *kcontrol)

성공하면 0을 반환하고, 실패하면 0이 아닌 에러코드를 반환한다.

사용예는 다음과 같다:
if ((err = snd_ctl_add(card, snd_ctl_new1(&xxx_contols[idx], chip))) < 0)
  return err;

1.3.7.2 snd_ctl_new1 #

제어기에 대한 정보를 쉽게 생성시킬 수 있도록 도와주는 함수이다.

함수의 원형은 다음과 같다:
snd_kctonrol_t *snd_ctl_new1(const snd_kcontol_new_t *ncontrol, void *private_data)

사용예는 다음과 같다:
if ((err = snd_ctl_add(card, snd_ctl_new1(&xxx_contols[idx], chip))) < 0)
  return err;

last modified 2006-04-12 00:35:15
ShowPage|FindPage|DeletePage|LikePages Valid XHTML 1.0! Valid CSS! powered by MoniWiki
0.0910 sec