BLOG ARTICLE Sound | 2 ARTICLE FOUND

  1. 2006.09.15 Sound Programming
  2. 2006.09.13 Sound Play Class

Sound Programming


[ Audio-1 ]      [Audio-2]      [ OSS ] 
[Play Programing,Recording Programing] 


--------------------------------------------------------------------------------


1.OSS

Open Sound System(OSS)은 UNIX, LINUX 등 여러 운영체제의 사운드 카드 드라이버이다.
OSS는 저수준의 API를 제공하며 이를 이용하여 OSS devices 그리고 mixer,audio,MIDI,raw
musix,Virtual Mixer,SoftOSS device를 프로그래밍 할 수 있다. 아울러 이문서는
http://www.opensound.com 의 "Open Sound System Programmer's Guide ver 1.11"중
에서 playback 과 recording을 위한 Audio 부분만을 골라 편집하여 번역한 것이다 

2.Device Files Supported by OSS

*OSS API는 soundcard.h 에 선언되어 있다


*/dev/mixer
*/dev/sndstat
*/dev/dsp 그리고 /dev/audio
*/dev/sequencer
*/dev/music(/dev/sequencer)
*/dev/midi
*/dev/dmfm
*/dev/dmmidi

2-1. /dev/dsp and /dev/audio

/dev/dsp 그리고 /dev/audio 는 음성을 기계화(digitized)시키는 주된 장치화일이다. 어떤
음성 데이터도 사운드 카드의 DAC/PCM/DSP 와 /dsv/dsp 그리고 /dev/audio 에 읽거나
써서 재생 또는 녹음을 한다 .
dev/dsp 와 /dev/audio 는 매우 유사하나 dsv/audio는 loigarithmic mu-law encoding을
사용하며 dsv/dsp는 8-bit unsigned linear encoding을 사용한다. 이 화일들은 ioctl 프로
시저를 이용하여 제어할수 있다 (-dev/audio는 SunOS에서 사용하기에 적합하다.)


Audio programing

1.introduction

*기본적인 programming 방법

1. 장치들를 열고 8kHz mono mode를 작동 시킨다

2. encoding 은 ioctl 프로시저를 호출 함으로 서 바꾸는 것이 가능 해진다 ,후에 모든 장치
  화일들 은 유사하게 행동한다.


그러나 나중에 정의된 ioctl 프로시저를 호출 하는것에 의하여 장치들의 많은 파라 미터를
바꾸는 것이 가능하다. 모든 codec 장치들은 기록, 재생 능력을 가지고 있으나 전혀 기록(
레코딩),재생 기능을 가지고 있지 않은 장치들도 있다. 그러나 대부분의 audio 장치는 이런
기능을 가지고 있다.
동시에 레코딩 재생을 하는 장치들을 전이중 (full duplex)장치라고 부른다. 가장일반적인 사운드 데이타로 레코딩,재생 하는 방법은 UNIX,LINUX 명령어 (dd,cat )를 사용하는 것이다.예를들면

*녹음 : cat  /dev/dsp > xyz : (오디오 장치에서 디스크화일로 명령어가 kill할때 까지 저장
                                        한다.)

*재생 : cat  xyz > /dev/dsp 

오디오 장치는 항상 exclusively 하게 열린다. 만약 하나의 프로그램이 그것 이 이미 open상태일떄 장치를 열려고 한다면 사운드 드라이버는 즉시 에러 (EBUSY)를 를 RETURN 할것이다.


1. Declarations for an Audio Program


OSS API를 사용하는 프로그램은 <soundcard.h> C언어 헤더 를 포함해야 한다. 그리고 그
밖의 화일을 다루기 위한 헤더를 포함한다.


/****Listing1 - Definitions for an Audio Program*****/

/********* Standard includes************/

#include <ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/soundcard.h>

/********* Mandatory variables.**********/

#define BUF_SIZE 4096
int audio_fd;
unsigned char audio_buffer[BUF_SIZE];

*BUF_SIZE 매크로는 audio의 data를 위하여 할당해진 버퍼의 크기를 정의한다.(-그러나 짧은 버퍼가 결과를 더잘 recording 해준다.버퍼사이즈는 1024(linux) 4096사이에서 의 선택이 좋다)


2. Selecting and Opening the Sound Device

audio장치는 사용되기 전에 open해야한다. 만약 프로그램에 encoding format 이 장착되지
않았다면 올바른 장치 화일을 open하는것이 중요하다. 이창치 화일들은 실제 디바이스화일의
심볼릭 링크이다
예를들면 /dev/dsp 는 /dev/dsp0를 가르킨다(이것은 오디오장치가 시스템에서 처음 탐색
하는 화일이다)장치 화일을 열었다면 오직 O_RDONRY 와 O_WRONRY만을 쓸것을 권장한다.
O_RDWR는 Full duplex(동시에 재생과 녹음을 한다.)에서 사용되어야 한다


/********Listing 2 - Opening a Device File***********/

if ((audio_fd = open(DEVICE_NAME, open_mode, 0)) == -1)
{
       /* Open of device failed */

      perror(DEVICE_NAME);
       exit(1);
}


*error 중 유일하게  EBUSY (Device busy )는 장치가 결코 이용할 수 있게 될것이라는 것이 보장되지 않을 지라도
프로그램이 다시한번 같은시간에 장치화일을 열려고 노력한다


3. A Simple Recording Application


/***********Listing 3 - Sound Recording**********/


int len;
if ((len = read(audio_fd, audio_buffer, count)) == -1) 
{
       perror("audio read");
       exit(1);
}

위 예에서 count는 프로그램이 장치로부터 읽기를 원한 바이트들의 수를 정의합니다. 그것은
적은  audio buffer의 크기와 같다. 덧붙이자면 그것은 또한 항상 sample크기의 정수형 배
수이다 그리고 그것은 2의 정수형을 사용한다 (2,4,8,16,32)그리고 이것은 내적으로 드라이
버에 의하여 사용될때 최고로 작동된다.
장치로부터 기록된 바이트들의 수가 정확하게 시간을 재는데 사용될수있다. 오디오 데이터
속도는 (data rate) (bytes per secound)는 샘플 스피드와 크기 그리고 채널의 수에 의존한다.


4. Simple Playback Application


재생 프로그램 역시 레코딩 프로그램과 같다 . 차이점은 재생 프로그램은 write 프로시저를
호출 한다는 점이다.


5. Setting Sampling Parameters


*음질에 영향을 미치는 세 파라미터들


1.sample format (때떄로 number of bits 라고 불린다)

2,number of channels (mono or stereo),

3,sampling rate(속도)

디바이스 는 새로운 샘풀링 파라미터를 받아들이기 전에 SNDCTL_DSP_RESET 으로 reset 을
한다.


6. Selecting Audio Format


샘플 포맷은 오디오 데이타의 질에 영향을 끼치는 중요한 요소이다. OSS API는 여러 다른
샘풀 포맷을 지원한다
<soundcard.h> 헤더 화일이 다음의 견본 포맷 identifiers의 경계를 정한다.


Name
Description

AFMT_QUERY
오디오 포맷이 아니다 그러나 현재오디오 포맷의 포맷에 대해 질문을 할때 사용되는 indentifier이다.

AFMT_MU_LAW
  Logarithmic mu-law audio encoding

AFMT_A_LAW
Logarithmic A-law audio encoding (rarely used)

AFMT_IMA_ADPCM
  4:1 로 압축된 현재 16-bit 오디오로 대표되는  평균 4bit per sample의  포맷이다. 이것은 여러 다른 ADPCM 포맷이있다 . IMA ( interactive Multimedia Association,대화형 멀티 협회)에 의하여 하나가 정의 되고. 또한 Creative ADPCM  format은 SoundBlaster16에 의하여 사용된 ADPCM 포맷이 이것을 가지고 부합하지 않습니다.AFMT_U8 : The standard unsigned 8-bit audio encoding used in PC soundcards.

AFMT_S16_LE
The standard 16-bit signed little-endian (Intel) sample format used in PC soundcards

AFMT_S16_BE
Big-endian (M68K, PowerPC, SPARC, etc.) variant of the 16-bit signed format.

AFMT_S16_NE
16-bit signed format in machine's native endian convention.

AFMT_S8
Signed 8-bit audio format.

AFMT_S32_LE
Signed little-endian 32-bit format. Used for 24-bit audio data where the data is stored in the 24 most significant bits and the least significant 8 bits are not used(should be set to 0).

AFMT_S32_BE
Signed big-endian 32-bit format. Used for 24-bit audio data where the data is

AFMT_U16_LE
Unsigned little-endian 16-bit format.

AFMT_U16_BE
Unsigned big-endian 16-bit format.

AFMT_MPEG MPEG MP2/MP3
audio format (currently not supported).

               <Table 1 - Sound Sample Formats>


하드웨어 레벨에서 대부분의 장치들이  8-bit unsigned format ( AFMT U8 ) 을 지지한다는
것은 중요한 사실이다( 비록 그것들이 16-bit format의 high-end device를 제공하더라도 ).
다른 일반적인  format은 AFMT_S16_LE 와 AFMT_MU_LAW이다. 많은 장치들을 가지고
AFMT_MU_LAW 는 소프트웨어에서 기본 번역기로 제공하는 mu-law와 8-bit encoding 와
경쟁한다. 이것은 오직 8bit를 사용 할때 보다 낮은 음질이 생기는 원인이 된다. 어플리 케이
션은  장치에 의하여 그들이 요구하는 견본 포맷이 지지된다는 것을 검사해야 한다. 지원 되지
않는 포맷의 작업은 데이터를 다른 포맷으로 바꾸어 주어야 한다. (보통 AFMT_U8). 양자
택일적으로 , 프로그램은 그것이 전환을 할 수 없다면 중단해야 한다.

AFMT_S32_XX FORMAT은 애플리케이션이 16-bit 샘플사이즈 이상을 요구하였을 때 사용
하기 위하여 만들어졌다. 하나의 샘플을 32-bit로 저장 할당 할때 int 는 최고의 아키텍쳐이다.
24 bit 의 데이터는 3개의 중요한 bytes로 저장 되어야 한다 (가장 중요한 바이트는 0으로
쎄팅 되어야한다).


the number of bits required to store a sample is:


* 4 bits for the IMA ADPCM format,


* 8 bits for 8-bit formats, mu-law and A-law,


* 16 bits for the 16-bit formats


* 32 bits for the 24/32 bit formats.

* MPEG audio format.

샘플 포맷은 ioctl ,SNDCTL_DSP_SETFM을 사용하여 설치할수있다. 다음의 코드는 오디오
포맷을 AFMT_S16_LE(다른 포맷과 유사한)로 설치 한것이다


/***************Listing 4 - Setting Sample Format****************/

int format;
format = AFMT_S16_LE;


if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1)
{
       /* fatal error */
       perror("SNDCTL_DSP_SETFMT");
       exit(1);
}

if (format != AFMT_S16_LE)
       /* The device doesn't support the requested audio format. The
       program should use another format (for example the one returned
       in "format") or alternatively it must display an error message
       and to abort. */

The SNDCTL_DSP_SETFMT ioctl call simply returns the currently used format if
AFMT_QUERY is passed as the argument.


만약 AFMT_QUERY argument 가 설정되어있다면 SNDCTL_DSP_SETFMT iocl 호출은 단
순하게 현제 사용되고 있는 format을 return 한다. ioc시 호출로 현재 사용하는 format을 체
크하는 것은 아주 중요한 일이다. 만약 사용할 특별한 포맷이 하드웨어에서 제공되지 않는
다면 다른 시스템 콜을 거절하고 다른 포맷을 제공한다.


/***********Listing 5 - Checking for Supported Formats************/


int mask;
if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &mask) == -1)
       /* Handle fatal error ... */

if (mask & AFMT_MPEG)
       /* The device supports MPEG format ... */


*NOTE*


SNDCTL_DSP_GETFMTS 는 실제로 하드웨어에서 제공되는 포맷만을 리턴 한다. 그것은
드라이버에서 제공되는 포맷이 더 많은 종류의 소프트웨어 변화를 사용 가능 하게 만
든다.(signed to unsigned, big-endian to little-endian or 8bit to 16-bit). 이러한 포맷들의
우열은 ioctl에 의해서 리포트 되지는 않는다 그러나 SNDCL_DSP_SETFMT는 그것들을 받
아들인다.
FMT_MU_LAW는 거의 모든 장치에서 지원대는 데이터 포맷이다. OSS 버전 3.6 에서는 항상
위의 포맷이  NDCTL_DSP_GETFMTS  으로 제공 되었다. 버젼 3.6 그리고 나중의 버전에
서는  장치가 하드웨어안에서 mu-law 포맷을 지한다. 이 엔코딩은 오직 어프리케이션 그리고
시스템이 mu-law 엔코딩을 사용하는 오디오 파일에서 사용된다


7. Selecting the Number of Channels (Mono/Stereo)

기본  모드는 mono이지만 거의 대부분의 장치는 stereo를 지원한다. 어플리케이션은 ioctl
호출로 채널의 수를 선택한다. SNDCTLl_DSP_CHANNELS은 argument와 함께 채널의 수를
지정할수있다.
대부분의 디바이스 장치는 16개의 채널을 지원한다. 미래의 장치는 점점더 지원하는 채널
수가 늘어날 것다

Listing  6. Setting Number of Channels

int channels = 2; /********* 1=mono, 2=stereo ***********/
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
{
       /* Fatal error */
       perror("SNDCTL_DSP_CHANNELS");
       exit(1);
}
if (channels != 2)
       /* The device doesn't support stereo mode ... */

*NOTE


어플리 케이션은 sampling speed를 선택 하기전에 채널의수와 비트의 수를 꼭 선택 하여
야만 한다.  장치들은  모노와 스테레오의 최대 스피드를 가지고 있다.카드의 최대 스피드모
드로  장착한 후에  프로그램이 부정확하게 채널의 수를 바꾼다면 프로그램은 부정확하게
행동할것이다.  스피드는 처음 장치에서 읽거나 쓰기전에 선택하여야만 한다.


8. Selecting Sampling Rate (speed)


샘플링 속도는 오디오의 음질을 결정하는 중요한  매개 변수이다. OSS API는 1HZ에서 2GHz
까지의 주파수의 선택을 허가한다. 그러나 실제로는 오디오 장치에 존재 하고 사용하는 것은
제한되어 있다 . 최대 주파수가 넓게 변화되는 동안 최소의 주파수는 보통 5kHz 이다몆개의
오래된 사운드 카드는 재생시에는 22.05kHz 레코딩시에는 11.025kHz를 이용하고 다음의
세대는 44.1kHz (모노) 혹은 22.05kHz(스테레오)를 제공한다 
최대의 사운드 카드는 최대 96kHz(DVD 음질)을 제공한다 그러나 일반적으로 제공되는 것은
44.1kHz(CD음질)이다.
기본 샘풀링 속도는 8kHz이다.그러나 어플리케이션은 그런것에 의존하지 않는다 디바이스
장치의 제공이높으면 높게 제공이 된다. 코덱장치는 보통 높은주파수의  crystal oscillator
스피드 눈금 에 의해 샘풀링 눈금을 만들어 낸다. 다음은 샘플링 스피드를 설정하는 프로그램
코드이다 .


/************Listing 7 - Setting Sampling Rate*********/

int speed = 11025;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
{
       /* Fatal error */
       perror("SNDCTL_DSP_SPEED");
       exit(Error code);
}
if ( /* returned speed differs significantly from the requested one... */ )         /* The device doesn't support the requested speed... */

NOTE

어플리케이션은 샘풀링 스피드를 설정하기 전에 채널의 수와 비트의 수를 선택해야 한다 .
장치들마다 다른 모노와 스테레오의 스피드를 가지고 있다 . 만약 카드에 채널의 수가 에 높은
스피드 모드가 설정된이후에 바뀐다면 프로그램은 부정확한 행동을 할 것이다. 샘플링 스피
드느 처음 읽거나 쓰기전에 장체에 설정 되어야 한다.


9. Other Commonly Used ioctl Calls


ioctl 프로시저 호출을 하지 않고  오디오 처리 프로그램을 하는 것은 가능 하다. 그것은 다른
3가지가 이미 초기에 기술 되어있기 때문이다.
눈에 띄는 delay나 pause없이 어플리케이션에서 이미 paramenters를 호출하여 장치를 열어
잇따라 연속적으로 읽거나 쓴후에 파일을 닫는 것은 것은 가능하다 이러한 종류의 어플리
케이션은 stream이나 batch apllication으로 described 되어있다 이러한 추가의 3가지 호출은
아마도 약간은 더 까다로운 프로그래밍을 요구할것이다. 모든 그러한 것들은 argument를
요구하거나 리턴 하지않는다 (just use an argument of 0)

ioctl SNDCTL_DSP_SYNC 는 어플리케이션이 장치에 played시에 마지막 바이트를 쓸데까지
기다리기를(wait)원할 때   사용한다 (그것은 recoding 모드에서는 되지않는다) 그러한 경
우엔 시스템 호출은 장치를 reset(stop)한다 그리고 호출한 프로그램으로 돌아가 리턴한다.
이러한 호출은 아마도 몇몇의 두 번째 수행의 버퍼의 데이터에 의존한다.  은연중에 어떤 사
운드 장치 호출도 SNDCTL_DSP_SYNC 로 종료한다. SNDC시_DSP_SYNC 는 장치를 close
하거나 reopen 할시에  사용하는 것이 좋다. ioctl SNDCTL_DSP_RESET는 즉시 장치를 멈
추고 그리고 그것이 새로운 파라미터들을 받아들일 수 있는 상태로 그것을 돌려줍니다 . 장
치를 openning 한후에 호출 하였을때 불리한 효과가 있다 이호출은 오직 레코딩중에
playback이 abort를 필요로 할때만 요구한다 .

일반적으로 장치의 열고 닫는 것은 SNDCTL_DSP_RESET를 사용한 후에 할 것을 추천 한다

<ioctl SNDCTL_DSP_POST는 SNDCTL_DSP_SYNC의 lightweight 버전이다. 그것은 단지 드라이버가 출력중의 정
  지 일것같다고 말한다 이것은 장치 좀더 괜찮은 정지를 핸들링이 가능하게 해준다>

NOTE
그들 모드는클릭 혹은 출력중의 불필요한 정지로  ioctl을 호출한다. 프로그래머는 단지 절
대적으로 요구할때만 사용 하여야 한다. 프로그래머는 자신의 프로그램에서 오디오 데이타가
비교적 오랜시간 출력이 멈추었을때SNDCTL_DSP_POST를 사용 하여야한다.


-예를 들면 이런 종류의 상태는 다음과 같다:


*재생 후에 즉시 효과가 나타나지 않을 때


*사용자의 입력을 기다리는 적용시간들 전에

*그러한 큰 메모리 파일이 로딩시에 오래 작동 하기 전에


프로시저  SNDCTL_DSP_RESET 혹은 SNDCTL_DSP_SYNC 는 어플리 케이션이 샘플 파라
미터(스피드 채널의 수 혹은 비트의수)를  호출한다. 파라메터의 변화에 순간에 장치를 열고
닫는 것이 더 신뢰성이있다. 어플리케이션은 레코딩이나 재생을 바꿔주기 전
에SNDCTL_DSP_SYNC 혹은SNDCTL_DSP_RESET을 호출한다 (혹은 이런경우엔 장치를
열고 닫는 것을 더 추천 한다 ).

10. Interpreting Audio Data

오디오 데이터의 엔코딩은 샘플의 포맷에 의존한다

11. Mu-law (Logarithmic Encoding)

하이 포맷은 디지털 전화 기술에서 기원 되었다. 각 샘플은 본래는 16비트 값인데 8비트로 압축하여 묘사한다. 만기된 logaruthmic 엔코딩은 그 포맷이 사용되기 전에 선형의 포맷으로 바뀐다.(two mu-law encoded values cannot simply be add)
-가능하다면 mu-law를 피하라 그리고 그 대신 8 , 또한 16-bit 선의 포맷들을 사용해라.

*8-bit Unsigned

이것은 일반적으로 모든 사운드 카드(S/B)의 포맷이다 또한 거의 모든 하드웨어에 제공된다. 각각의 샘플은 8비트로 저장된다.  0은 제일작은 레벨을 나타내고 255는 최고의 레벨을 나타낸다. 자연스러운 레벨은 128이다(0x80 (16진법)) 그러나  이것은 조용한 가운데에서 레코딩을 진행해도 약간의 소음이있다 그래서 바이트값 127(0x7f)에서 129(0x81)사이에 변화를 준다. C언어에서 의 데이터 값으로는 unsigned char형을 사용한다 . signed 8-bit 포맷에서 unsigned 바꾸기 위하여 128의 값을 가감하여 바꾼다.

*16-bit Signed

16비트 포맷으로 작업을 해야 할땐 주의해야 할점이있다. 16비트 데이터는cpu와 오디오 장치의 설계에 의존하여 이식할수 없다. 상황이 정상적인 soundcard를 가지고 little-endian을 사용하는  x86 CPU를 사용할 때에는  간결하다. 이러한 경우는 cpu와 사운드카드가 같은 16bit 엔코딩을 사용할때이다 그러나 위와 같지 않다면 그렇지는 않다.
16 비트 엔코딩은 일반적으로 little-endian(byte ordering)같은 사운드 하드웨어에서 AFMT_S16_LE로 사용한다. 그러나  다른 기계들은 오직 오디오 칩에 big-endian만을 제공한다.
16비트 signed 데이터는 c언어에서 사용될시에는 signed short로 사용 되는 것이 제일 적합하다 그러나 이러한 사실은 오직 little-endian 머신에서만 적합되는 말이다. 덧붙여서 C  표준에서는 데이터 타입을 정의 하지 않았다 그래서 short가 16비트의 머신에 적합한지는 아무도 보증을 해줄수 없다. 이러한 이유로 unsigned short 형의 array를 사용할시에는 신중해야 한다.
적당한 방법은 array of unsigned char를 사용하는 것이다 그리고   드라이버에 pass 하기전에 직접 assemble/disassemble the buffer해버리는 것이다 .

NOTE
*참고로 byte ordering을 해주는 함수로는
*Unsigned short interger
  htons() : host -to- network 바이트변환
  ntohs() : network -to- host
*Unsigned long interger 변환
  htonl() :host -to-network
  nyohl() :network -to-host


/*****************Listing 9 - Handling 16-bit Data ****************/

unsigned char devbuf[4096];//8bit,apllication의 2배가있어야 받아들이수있다.
int applicbuf[2048];//16bit
int i, p=0;

/********* Place 2048 16-bit samples into applicbuf[] here **********/

for (i=0; i<2048; i+=2)
{
       /* first send the low byte then the high byte */
       devbuf[p++] = (unsigned char)(applicbuf[i] & 0xff);
       devbuf[p++] = (unsigned char)((applicbuf[i] >> 8) & 0xff);
}

/********** Write the data to the device*********/

      < 풀   이 >

char  => 8 bit =>unsigned char devbuf[p]
int     =>16 bit =>int applicbuf[p]

11110111 00110010
00000000 11111111
_________________ & 
        00110010 devbuf[0]=00110010

11111111 11110111            
00000000 11111111 &
_________________
        11110111 devbuf[1]=111100111    

AFMT_S16_NE 포맷은 프로그램에서  encoding 이나 decoding을 원할 때 사용하는forma
t이다.그것은 자동적으로 올바른 cpu구조의 포맷을 찾아내어준다. 이러한 방법은 보통 단순
하게 signed short format 샘플을 저장하는 것을 가능하게 해준다


24 and 32 bit signet formats


AFMT_S32_S32_LE ,AFMT_S32_BE, 그리고 AFMT_S32_NE 포맷은 32bit-signed포맷이다
데이터는 왼쪽부터 저장하며 사용하지 않는 비트는 0으로 설정한다


13. Multiple channels


OSS는 전문적인 멀티 오디오 장치 채널을 제공한다  디바이스는 2개의 다른 다중채널의 핸
들링에 의존한다.
이 방법안에(서) 복합적인 채널들을 지지하는 단지 하나의 장치 파일(/dev/dsp)이 있다. 어플리 케이션은 단순하게  SNDLC_DSP_CHANNELS  ioctl을 사용하여 multiple channels(2,3,4,...,N)을 요구합니다.

*Multiple audio device method

여러 장치 파일들(dev/dspM ,dev/dspM+N   : M=처음 채널의 장치 넘버  N= 채널의 넘버 ) 이방법은 같은  같은 애플리케이션 혹은 여러 부분들의 애플리케이션에서 채널을 개별적으로Open 할 것이다 그것은 또한 여러 장치 파일들이 stereo pairs처럼 조직화 되는 것이 가능하다(/dev/dspM = channels0/1, dev/dspM+1=channels2/3,etc)  

*Mixed multi device and interleaved method

디바이스들은 독립된 복합적인 디바이스 화일을 준다.  거의 무한한 유연성을 제공하는 3번째 방법을 사용하기에 가능합니다.   

이 방법은 하나의 어플리케이션이 하나의 파일( /dev/dsp0)을 열수있게 한다. 그리고 그것은 스테레오 (2 channel)모드(이것은 /dev/dsp1의 보류된 채널을 장착한다 ) 이다. 다른 어플리케이션은 아마도 /dev/dsp2를 열것이고 그리고 그것은 4채널모드일 것이다 (그래서 채널은 /den/dsp3./dev/dsp4 그리고 /dev/dsp5을 할당해 얻을 것이다.) 최후의 세번쨰그리고 네번째 어플리케이션은 /dev/dsp6 그리고 /dev/dsp7을 open할 것이다 그리고 그것들은 mono 모드를 사용할 것이다 . 모든 가능한 채널은 제한이 복합적이다

14. Changing mixer settings for an audio device

일반적으로 오디오 어플리케니션이 mixer 세팅을 건드리지 않을 것을 권장한다. 사용자는 믹서 전용 프로그램으로 믹서 쎄팅하기 때문이다. 만약 그렇지 않다면 프로그램들은 서로 충돌하게 될것이다. 적어도 어플리케이션이  위의 문제를 염두에 두어야 믹서의 적용부분을 깨지않는다. 믹서의 제공이 깨지기 때문에 실패한 애플리 케이션은 너무나 많다.

만약 프로그래머가 그래도 믹서를 변화시키겠다면 아래의 방법을 따라라

1) 어떤 /dev/mixer# 장치도 열지 않고 대신 mixer ioctl(OSS 문서 중 믹서 프로그램 부분을 참조 바람 )을 오디오 장치 파일에서 직접 호출 해라 프로그래머는 믹서 접근을 위하여 다시 장치를 재개하려고 노력 하지 말아야 한다.

2)오직 PCM(PCM은 아날로그 데이터 전송을 위한 디지털 설계이다. ) 볼륨과 레코딩 디바이스 세팅을 바꿀수 있다. 그것들은 같은 방법으로 모든 디바이스를 콘트롤 한다  만약 같은 믹서 제어가 실패해도 그것은 에러 상태가 아니다.

3)만약 너가 믹서를 접근할시 어떤 종류의 에러를 만났을때 그것을 무시하거나 혹은 멈추하하거나 게다가 믹서를 작동 시킨다면  당신이 할수 잇는 가장큰 실수는 믹서 때문에 어플리 케이션을 중단 시키는 것이다.

위에 나와있는 말들은 OSS 의 오디오 어플리 케이션의 프로그래밍을 할때 기초가 되는 부분 들이다 그러나 그것들은 게임과 같은  실시간 오디오 어플리케이션 ,음성 회의 시스템 ,음성분석툴 , 다른 많은 처리 들을 하기위해서는  더많은 기술을 요구로 한다 이러한 것들 고급 프로그래밍 부분(Advanced Programming Topics)에서 다루고 있다 . 그러나 위의 부분 들을 잘 이해 하고 있다면 많은 오디오 관련 프로그래밍을 할때에 큰 힘이 될것이다.

AND

using System;
using System.IO;
using System.Runtime.InteropServices;

public class Sound
{
   private byte[] m_soundBytes;
   private string m_fileName;

   private enum Flags
   {
       SND_SYNC = 0x0000,  /* play synchronously (default) */
       SND_ASYNC = 0x0001,  /* play asynchronously */
       SND_NODEFAULT = 0x0002,  /* silence (!default) if sound not found */
       SND_MEMORY = 0x0004,  /* pszSound points to a memory file */
       SND_LOOP = 0x0008,  /* loop the sound until next sndPlaySound */
       SND_NOSTOP = 0x0010,  /* don't stop any currently playing sound */
       SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */
       SND_ALIAS = 0x00010000, /* name is a registry alias */
       SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */
       SND_FILENAME = 0x00020000, /* name is file name */
       SND_RESOURCE = 0x00040004  /* name is resource name or atom */
   }

   [DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)]
   private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags);

   [DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)]
   private extern static int WCE_PlaySoundBytes(byte[] szSound, IntPtr hMod, int flags);

   /// <summary>
   /// Construct the Sound object to play sound data from the specified file.
   /// </summary>
   public Sound(string fileName)
   {
       m_fileName = fileName;
   }

   /// <summary>
   /// Construct the Sound object to play sound data from the specified stream.
   /// </summary>
   public Sound(Stream stream)
   {
       // read the data from the stream
       m_soundBytes = new byte[stream.Length];
       stream.Read(m_soundBytes, 0, (int)stream.Length);
   }

   /// <summary>
   /// Play the sound
   /// </summary>
   public void Play()
   {
       // if a file name has been registered, call WCE_PlaySound,
       //  otherwise call WCE_PlaySoundBytes
       if (m_fileName != null)
           WCE_PlaySound(m_fileName, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_FILENAME));
       else
           WCE_PlaySoundBytes(m_soundBytes, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_MEMORY));
   }
}

PDA에서 소리 파일을 재생할 수 있는 팁.
Sound 객체 생성 후 play() 메소드 사용. 비동기로 작동함.
참조: http://msdn2.microsoft.com/en-us/library/ms229685.aspx

'Computer > .NET Compact Framework' 카테고리의 다른 글

PDA 전원 정보  (0) 2006.09.13
AND