2010년 4월 9일 금요일

리눅스 멀티미디어 프로그래밍

1. Linux용 멀티미디어 환경

 (1) 사운드

  •  기본적으로 리눅스에서는 커널 차원에서 사운드 드라이버를 지원한다.
  • 리눅스 지원 사운드 드라이버
    • 리눅스 커널과 함께 배포된 것(OSS/Free)
    • 상업용 드라이버 OSS
    • 무료로 배포되고 있는 ALSA
  • 커널 표준 사운드 드라이버
    • OSS/Free라고도 불리우며 4Front Technologies 사에서 OSS 개발을 하고 있는 Hanu Savolainen씨가 대부분을 개발했다. 지금도 OSS에서 무상 드라이버를 기부하여 이에 대응하는 사운드 카드는 점점 늘어가고 있다.
  • OSS(Open Sound System)
    • 미국의 4Front Technologes라는 회사가 개발하여 배포하고 있는 사운드 드라이버로 자유롭게 사용할 수 있는 것과 상업용이 있다.
  • ALSA(Advanced Linux Sound Architecture)
    • Jaroslav Kysela(체코 거주)가 메인 프로그래머로서 활동하고 있는 ALSA Project에서 제작, 배포하고 있는 자유 Linux용 사운드 드라이버, GPL에 의한 재배포가 가능함, 커널 표준 드라이버나 OSS 드라이버와의 호환성이 있어, 이들 드라이버용으로 작성된 프로그램의 대부분이 ALSA 드라이버에서 그대로 사용할 수 있다. 인스톨 과정이 좀 복잡함, 커널 2.4부터 자동으로 포함되어 있다.

  (2) 화상(Video)

  •  리눅스에서 지원하는 화상캡쳐 장치들로는 TV 수신카드와 영상 캡쳐 장치들 그리고 USB 화상 CAM 으로 나눌 수 있다.
    • Video4Linux
      • Kernel에서 지원하는 기본 모듈로 TV 수신카드를 지원하기 위해 등장.
    • Video4Linux2
      • Video4Linux 1.0 버전이 TV 수신카드를 위해 등장했기 때문에 화상 Cam에는 맞지 않기 때문에 USB Web CAM을 위해서 등장했다.
      • 화면의 확대/축소 기능 지원

2. Linux Sound 프로그래밍

 (1) 사운드 프로그래밍

  • 리눅스에서의 사운드 프로그래밍은 커널에서 제공해주는 API를 이용해서 만든다.
  • 리눅스 사운드에서 Degital Audio("/dev/dsp"), mixer("/dev/mixer"), MIDI, raw Music 그리고 synthesizer와 같은 장치들을 사용한다.
  • 기본적으로 사용되는 Device 장치들
    • /dev/dsp(Digital voice device)
      • 마이크로 사운드를 녹음하고 스피커로 사운드를 출력하기 위해 사용됨
    • /dev/mixer(mixer)
      • 사운드 볼륨을 조절할 때 사용됨, 마이크의 입력 방향 설정 가능
    • /dev/sequencer(Synthesizer)
      • 사운드로 효과를 만드는데 사용된다. 미리 녹음된 소리(악기 소리나 기타소리)를 합성해서 새로운 소리를 만든다.
    • /dev/music
      • 기본적으로는 "/dev/dsp"와 같다. 차이는 알고리즘 적으로 /dev/dsp는 8bit unsigned 선형(Linear) Encoding을 사용하고, /dev/music은 mu-law Encoding을 사용한다.
    • /dev/midi
      • MIDI 인터페이스를 이용해서 MIDI 장치들(Keyboards, synthesizers, stage props)을 연결하는데 사용된다.
  • 우리는 여기서 /dev/dsp를 이용해서 사운드를 입력 받아서 출력하는 어플을 작성

 (2) OSS API Basic

  • OSS API들은 <soundcard.h>라는 헤더파일에 정의되어 있다.
  • 위의 헤더파일은 보통 "/usr/include/sys"에 위치하고 있다.
  • OSS에서 장치의 값을 설정하고 읽어오는 방법은 ioctl() 함수를 이용한다.

 (3) Audio Programming

  • 디지털 오디오(Digital Audio)는 컴퓨터 외부로 소리를 표현하는 일반적인 방법이다.
  • 오디오 프로그래밍의 일반적인 방법
    • 오디오 장치를 open() 한다.
    • 환경을 설정한다.
    • 입출력을 위한 메모리(버퍼)를 설정한다.
    • Read/Write 작어
    • 사용이 끝난 오디오 장치를 close() 한다.
  • 우선 "/dev/dsp"를 사용하기 위해서는 open()을 이용해서 장치를 열어야 한다.

### fedora11에서는 커널에 기본적으로 /dev/dsp와 /dev/mixer가 모듈로 설치가 되어서 부팅후 모듈을 올려줘야 한다. 아래처럼 시스템 시작시 모듈로 올라가도록 해준다.

# vi /etc/rc.d/rc.local
 ...
modprobe snd-pcm-oss

 

 

 (4) 사운드 장치 열기

  • open()의 flag 값
    • O_RDONLY : 사운드 장치(보통 마이크)로부터 입력을 받을 때 사용한다.
    • O_WRONLY : 사운드 장치(뽀통 스피커)로 사운드를 출력할 때 사용한다.
    • O_RDWR : 사운드 장치에서 사운드를 입력과 출력을 동시에 할 경우 사용된다.
    • if( fd = open("/dev/dsp", O_WRONLY, 0) ) == -1 ){
          perror("OSS : error opening device\n");
          return -1;
      }

  • 사운드 장치를 사용할 수 없을 경우 -1을 반환한다. 만약 다른 프로그램에서 사운드 장치를 사용하고 있을 경우 "EBUSY"라고 에러값을 설정한다.

 

 

 (5) 샘플링 환경 설정하기

  • 사운드 장치를 open한 후에는 사운드 입출력을 하기 전에 기본적인 설정이 필요하다. 사운드 음질에 영향을 미치는 다음의 기본적인 세가지 parameter가 존재한다.
    • Sample format(number of bits)
    • Channel의 수(mono or stereo)
    • Sample Rate(spee)
  • 위의 설정은 순서대로 해야한다. 아래의 설정을 위의 설정보다 먼저하면 설정이 되지 않는다.

 

 

 (6) 오디오 포맷 설저하기

  • Sample format은 음질에 영향을 미치는 중요한 변수이다.
  • Sample format은 여러가지가 있지만 여기서 AFMF_S16_LE를 사용하겠다. AFMF_S16_LE는 Signed 16Bit Little Endian을 뜻한다. 이 포맷은 일반적인 PC의 사운드 카드에서 사용되고 있다.
  • 사운드 카드를 설정하기 위해서는 앞에서 설명한 ioctl()에 매개변수로 SNDCTL_DSP_SETFMT를 사용한다.
    format = AFMF_S16_LE;
    if( ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1 ){
        perror("SOUND_PCM_SETFMT");
        return -1;
    }

 

 

 (7) 채널의 수 설정하기

  • 현재 사용되는 대부분의 오디오 장치들은 Stereo모드를 지원한다. 기본적으로 설정되는 모드는 Mono이다.
  • ioctl()에 SNDCTL_DSP_CHANNELS을 사용해서 채널의 수를 선택할 수 있다.
  • Mono의 경우는 1이고, Stereo는 2이다.
  • stereo = 2; // 1 : mono, 2 : stereo
    if( ioctl(fd, SNDCTL_DSP_CHANNELS, &stereo) == -1 ){
        perror("SOUND_PCM_CHANNELS");
        return -1;
    }

 

 

 (8) Sampling Rate 설정하기

  • Sampleing Rate는 소리의 질을 결정하는 파라미터이다.
  • OSS API는 1Hz에서 2GHz의 대역을 지원한다. 기본적으로 지원되는 Sampling rate는 8kHz이다.
  • 전화기(음성)에서 기본적으로 사용하는 것이 8kHz이다. CD의 경우 44.1kHz, DVD의 경우 96kHz의 값을 가지고 있다.
  • 우리는 음성을 이용해서 녹음/재생할 것이므로 8kHz를 이용할 것이다.
  • ioctl()에 SNDCTL_DSP_SPEED를 이용하면 Sampling Rate를 선택할 수 있다.
  • rate = 8000;
    if( ioctl(fd, SNDCTL_DSP_SPEED, &rate) == -1 ){
        perror("SOUND_PCM_SPEED");
        return -1;
    }

 

 

 (9) Full Duplex 설정하기

  • 많은 장치들이 half duplex이다. Half duplex의 경우 Recording이나 Playing이 동시에 되지 않는다. 오직 한 번에 한 가지의 일을 할 수 있다.
  • 물론 다중 채널이 지원되는 경우 Recording과 Playing을 각각 다른 채널을 이용해서 하면 된다.
  • 단일 채널에 Full Duplex를 지원하기 위해서는 사운드 장치를 설치하기에 앞서서 Full Duplex로 설정해아 한다. 설정은 다음과 같다.
  • if( ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0) == -1){
        perror("SOUND_PCM_SETDUPLEX");
        return -1;
    }

 

 

 (10) 사운드 입/출력

  • 일반적으로 리눅스에서는 장치를 파일의 개념으로 사용한다.
  • 사운드를 입력받기 위해서는 파일을 읽는 것과 마찬가지로 read()를 사용한다.
  • if( status = read(fd, buf, count) ) == -1 ){
        perror(SOUND_READ_ERROR");
        return -1;
    }

  • 마친가지로 사운드를 출력하기 위해서는 write()를 사용한다.
  • if( status = write(fd, buf, count) ) == -1 ){
        perror("SOUND_WRITE_ERROR");
        return -1;
    }

  • 더 자세한 사항을 알고 싶으면 OSS API 문서를 참조하라.

 

 

 (11) 동시에 여러가지 일하기

  • 여러가지 일을 동시에 실행시키기 위해서는 thread나 멀티  proecess를 사용해야 한다. 이것들은 설정이 복잡하다. 그래서 여기서는 기본적으로 Qt에서 제공하는 QTimer를 사용하도록 한다.(자세한 내용은 출처를 참고한다.)

 

3. Video4Linx 프로그래밍

  • Video4Linux는 리눅스에서 비디오 장치들을 제어하고 사용하기 위한 API들의 모임이다.
  • 비디오 장치들로는 튜너를 가지고 있는 비디오 카드나 PC Web CAM과 같은 장치들을 들 수 있다. 튜너를 가지고 있는 장치들을 제어해서 TV나 AM/FM 라디오, TeleText등의 방송을 시청할 수 있다.
  • Video4Linux는 커널에 기본적으로 포함되어 있으므로 따로 설치할 필요가 없다.
  • 이 Video4Linux를 이용해서 X윈도우 상에서 TV를 볼 수 있는 프로그램으로는 xawtv나 xwintv 등이 있다.
  • 이 곳에서는 Philips Web Cam을 이용해서 프로그램할 것이다. 튜너를 가지고 있는 디바이스(BT848)도 거의 같은 방식으로 동작하기 때문에 프로그램을 적용하는데 무리가 없을 것으로 생각이 든다.
  • 비디오 화면을 캡쳐하는 순서(드라이버에 따라서는 mmap 등 일부의 조작이 그 기능이 없는 경우 malloc으로 메모리 버퍼를 잡을 수도 있다.)
    • Video4Linux 장비의 정보(사양)을 얻기
      • capture 카드에 관한 정보를 얻는다. 프로그램 내에서 capture 카드를 하나로 고정하고 있다면, 하지 않아도 된다.
    • 사용 가능한 채널 얻기
      • capture 카드로 사용 가능한 채널(영상 소스)의 종류를 취득한다. 이것도 위와 마찬가지로 프로그램 내에서 capture 카드를 하나로 고정하고 있다면, 하지 않아도 된다.
    • Capture할 채널의 설정
      • 앞에서 가져온 정보를 이용해서 capture 하는 채널을 선택한다. 동시에, 영상 신호의 포맷 종류(NTSC, PAL, SECAM 등)도 선택한다.
    • 파라미터 설정
      • 밝음(Brightness), 대비(Contrast), 휴(Hue) 등의 파라미터 설정한다.
    • 메모리 공간 할당
      • malloc이나 mmap의 시스템 콜을 이용해서 캡쳐할 영상이 저장될 메모리 기억공간(buffer)을 확보한다.
    • Capture 시작하기
      • 앞에서 확보한 메모리 공간에 capture가 되도록 한다.
    • Capture 종료까지 기다리기
      • 그 밖에 하는 것이 없으면, capture 처리가 종료될 때까지 기다린다.
    • 화성처리
      • capture한 버퍼 내의 영상 데이터를 원하는 목적으로 처리한다. 이 과정에서 화면에 영상을 표시할 수 있다.
  • 더 자세한 내용은 출처를 참고한다.

 

 

출처 : 리눅스 멀티미디어 프로그래밍

댓글 없음:

댓글 쓰기