2010년 6월 11일 금요일

아이폰의 성공 비결

1. 스마트폰 개발을 위해 지난 4년간 내로라하는 우수 인력 100여명을 투입해서 아이폰 한 종류만 만들었다. 타 업체는 매년 수십종의 휴대폰을 내놓음.

2. 제품 개발의 일관성과 책임성 : 톱 매니지먼트가 직접 제품을 기획한 후 디자인 및 개발 전과정을 직접 지휘했다는 점이 완성도 높은 제품 출시를 가능하게 했다는 설명

3. '뉴톤', '아이팟폰' 등 실패작에서 사용했던 기술이 지금의 아이폰의 바탕을 이룸.

4. 무엇보다 가장 큰 성공이유 : 애플 CEO가 스티브 잡스라서ㅋㅋㅋ(스티브 잡스는 UX 전공자가 아니면서도 현존하는 최고의 UX 디자이너)

 

* 다변하는 모바일 생태계에서 기업이 생존하기 위한 조건 : 일관성(coherence)

 - 서로 다른 것들이 잘 뭉쳐서 전체를 구성하는 것

 - 마치 소설에서 '기승전결'을 따라가며 이야기가 변하지만 주제의 일관성만은 헤치지 않는 것처럼.

 - 다만 표준화와 규격화를 지향하는 '획일적 일관성(consistency)은 버려야 한다.

 - 심리스 UX를 구현하기 위한 '은은한 일관성'이 필요하다.

 - 애플 TV와 아이팟의 조작매뉴얼은 방식이 완전히 다르지만 말로 설명할 수 없는 애플 UX만의 냄새가 난다. 우리도 그것을 만들 수 있어야만 성공할 수 있다.

 

원문 주소 : http://www.zdnet.co.kr/Contents/2010/03/11/zdnet20100311161544.htm

 

2010년 5월 4일 화요일

드럼이란

* 드럼

  • 드럼은 영어로 북을 뜻하는 것으로 서양의 타악기 중의 하나이다.
  • 음악 그룹에서의 드럼은 일반적으로 여러 개의 북과 심벌즈로 이루어진 드럼셋을 의미한다.
  • 드럼셋은 사이드(크래시) 심벌, 탑(라이드) 심벌, 탐탐, 하이햇 심벌, 스네어 심벌, 플로어 탐, 스네어 드럼, 베이스 드럼(대고)로 일반적으로 구성된다.
  • 드럼 연주자를 지칭하는 말로도 쓰인다.
  • 드럼통은 둥근 원통을 이야기한다.

 

 

출처 : 위키백과

처음에 익혀야 할 기타코드

* 처음에 외워야 할 기타코드는 개방현을 이용한 메이저코드, 마이너코드, 세븐스 코드 정도다.(개방현이란 자판에서 아무것도 잡지 않은 기타줄을 말한다.)

 

* 기본적으로 외워야 할 코드

  • 메이저 코드 : C   D   E    F   G   A   B
  • 마이너 코드 : Cm Dm Em Fm Gm Am Bm
  • 세븐스 코드 : C7  D7  E7 F7  G7  A7  B7
  • 그   외 코드 : F#  F#m F#7

 

출처 : 해브원 블로그

기본음계에 대해

* 다장조 온음과 반음 관계에 대해서

  • 도     레     미     파     솔      라     시      도
  •    온음  온음  반음  온음  온음   온음  반음
  • 도와 도#의 관계는 반음 관계.
  • 도# = 레b

 

* 기타 자판과 음계

  • 도 레 미 파 솔 라 시 도
  • C  D  E  F  G  A  B  C

 

* 기타의 줄은 6개, 가장 두꺼운 쇠줄(6번)이 가장 윗 줄이다.

* 6번줄부터 1번줄까지 미라레솔시미로 맞춰져 있다.

 

출처 : 해브원 블로그

통기타 연주법에 대해

1. 스트로크

  •  통기타의 가장 기초가 되는 주법
  • 코드를 잡고 여러 개의 줄을 동시에 쳐주는 것을 말함
  • 기타 반주 그 자체로 볼 수 있음

2. 아르페지오

  • 우리말로 분산화음을 말하며 스트로크와는 달리 기본적으로 코드를 잡고 여러 줄을 치는 것이 아니라 한 음 한 음 팅겨주는 주법을 말함(엄밀히 말하면 핑거링 주법에 속한다고 볼 수도 있음)
  • 좀 조용하고 분위기 있는 음율에 많이 사용됨

3. 핑거링

  • 핑거스타일 주법으로 표현되기도 함
  • 피크를 사용하기보다 손가락을 이용하며, 주로 반주용이 아닌 하나의 곡을 연주하는 것을 말함.
  • 노래가 주가 되는 것이 아니라 기타연주 자체가 주가 되는 주법
  • 코타로 오시오나 유투브에서 정성하군 영상 참조

 

 

출처 : 해브원 블로그

2010년 4월 24일 토요일

유니버셜 디자인

< 유니버셜 디자인 >

 

1. 개념

  • Design for all people
  • 유니버셜 디자인은 "평생 디자인"이라고도 부르는 디자인계의 최신 주제(2010.4.)
  • 장애인, 노인, 어린이 등 약자가 사용할 수 있는 환경과 상품 창조를 만드는 디자인을 말하고, 신체적인 약함뿐 아니라 상황이나 나이에 따라 일어날 수 있는 특정 부분의 불리한 점을 보완하는 것이 "유니버셜 디자인"이다.
  • '더 편하게, 더 안전하게, 더 풍요롭게'를 외치는 소비자 중심의 생활 디자인이 지금 세계 디자이너가 추구하는 디자인의 중심이다.

 

2. 배경

  • 20세기 들어서 장애인, 고령자 등이 늘면서, 그들이 일상 생활을 자유롭게 보낼 수 있는 베리어 프리(barrier free) 개념이 등장했다.
  • 1980년 미국의 건축가이자 공업 디자이너인 론 메이스는 베리어 프리 개념을 뛰어넘는 남녀노소 누구나 사는데 불편함이 없는 디자인을 해야한다고 주장했고, 이 때 유니버셜 디자인이라는 개념이 생겨났다.
  • 유니버셜 디자인은 장애의 개념을 좀더 넓힌 디자인으로 정상인뿐 아니라 일시적 장애를 포함한 모든 장애를 어린이와 노인이 사용할 수 있는 환경과 상품창조를 추구하고, 이론적으로 생각하는 신체적 능력의 부족함만이 아니라, 상황이나 나이에 따라 모든 사람이 가지고 있는 특정부분의 취약성 모두를 장애의 개념으로 본다.

 

3. 원리

  • 기능적 자원성이 높은 디자인(Supportive Design)
    • 기능상 필요한 도움을 제공해야 하며 사용자에게 불필요한 어떤 부담도 야기시켜서는 안된다. 조명의 경우 밝기가 적절치 않으면 시각의 정확성이 떨어지며
  • 수용가능한 디자인(Adaptable Design)
    • 상품이나 환경이 상황에 따라 조절가능함으로써 다양한 요구를 충족시킬 수 있는 유통성을 지녀야 한다. 특히 오랜 시간 다양한 형태로 작업하는 사무환경에서는 인간공학적인 방법으로 이러한 특성의 디자인이 연구되어야 한다.
    • 변화 가능한 형태의 작업대나 높이조절이 가능한 책상과 스탠드, 다양한 서체와 글자의 크기조절이 가능한 컴퓨터 프로그램들이 이러한 사례이다.
    • 이러한 상품은 시각장애자와 노인들에게도 매우 유용하다.
  • 접근 가능한 디자인(Accessible Design)
    • 접근 가능성이란 장애물이 제거된 상태이다.
    • 보도블럭을 휠체어 사용자와 자전거를 타는 사람, 환자들이 편리하게 다닐 수 있도록 고려하고 아울러 시각장애자들에게도 도움이 되도록 색채와 패턴, 적절한 배치와 질감있는 재료를 사용해 시각장애로 인한 사고를 가능한 줄이는 것 등이 이러한 것들이다.
  • 안전한 디자인(Safely-oriental Design)
    • 대조적인 색채와 패턴으로 레벨차를 표시하거나 모서리를 둥글게 처리한 것 등 안전한 디자인은 보다 개성적이며 예반적이다. 또한 안전성은 심리적인 건강함, 소속감, 자기가치등을 포함한다.
    • 장애자가 정상정적인 활동을 유지할 수 있도록 고려된 공간은 개인에게 도립심을 부여함으로써 심리적인 건강을 유지시켜 준다.

 

 

< 7가지 원칙 >

  • 공평한 사용(Equitable)
    • 누구라도 차별감이나 불안감, 열등감을 느끼지 않고 공평하게 사용 가능한가?
  • 사용상의 융통성(Flexiblility in Use)
    • 서두르거나, 다양한 생활환경 조건에서도 정확하고 자유롭게 사용 가능한가?
  • 간단하고 직관적인 사용(Simple and Intutive)
    • 직감적으로 사용방법을 간단히 알 수 있도록 간결하고, 사용 시 피드백이 있는가?
  • 쉽게 인지할 수 있는 정보(Perceptive Information)
    • 정보구조가 간단하고, 복수의 전달수단을 통해 정보입수가 가능한가?
  • 오류에 대한 포용력(Tolerance for Error)
    • 사고를 방지하고, 잘못된 명령에도 원래 상태로 쉽게 복귀가 가능한가?
  • 적은 물리적 노력(Low Physical Effort)
    • 무의미한 반복동작이나, 무리한 힘을 들이지 않고 자연스런 자세로 사용이 가능한가?
  • 접근과 사용을 위한 충분한 공간(Size and Space for Approach and Use)
    • 이동이나 수납이 용이하고, 다양한 신체조건의 사용자와 도우미가 함께 사용이 가능한가?

 

 이와 같은 유니버셜 디자인은 제품이나 환경시설 외에 모든 산업을 대상으로 할 만큼 대단히 광범위하며, 근래 고령화의 급진전에 따른 고령친화산업(실버산업)의 부각은 기업에 있어서 새로운 비즈니스 창출 및 참여라는 기회를 제공하고 있습니다. 본격적인 고령사회의 도래와 와 국제화, 정보통신기술의 고도화 등에 동반하여 사회, 경제구조의 변혁, 가치관의 다양화 등이 한층 진전될 것으로 예측되는 향후 사회에 있어서 유니버셜 디자인은 더불어 사는 사회를 형성해가기 위해 필연적인 대안이라고 할 수 있습니다.

 

 

출처 : Our Blog, UDRC 유니버셜 디자인 연구센터

2010년 4월 20일 화요일

Qt4를 이용한 C++ GUI 프로그래밍-Chapter 01

(1) Hello Qt

  • 예제

1 #include <QApplication>
2 #include <QLabel>

3 int main(int argc, char *argv[])
4 {
5     QApplication app(argc, argv);
6     QLabel *label = new QLabel("Hello Qt!");
7     label->show();
8     return app.exec();
9 }

  • Qt의 모든 클래스는 자신의 이름과 똑같은 이름으로 된 헤더파일 내에 정의되어 있다.
  • 5번째 줄 : 응용 프로그램 차원의 자원을 관리하기 위해 QApplication 객체를 생성한다.
    • QApplication은 GUI 응용 프로그램 제어 흐름과 주요 설정 사항을 관리하는 클래스로서, 메인 이벤트 루프를 갖고 있으며, 응용 프로그램의 초기화와 종료화 그리고 시스템 차원의 설정사항과 응용 프로그램 차원의 설정사항을 다룬다.
    • Qt를 사용하는 GUI 응용 프로그램에는 하나의 QApplication 객체만이 존재할 수 있으며, 전역 포인터인 qApp 나 QCoreApplication::instance()를 통해 이 객체에 접근할 수 있다.(자세한 것은 Qt 어시스턴트 참조)
  • 명령행으로부터 입력되는 인자 중에서 Qt가 자체적으로 인식하는 것이 있기 때문에, QApplication을 생성할 때는 생성자에 argc와 argv를 넘겨줘야 한다.
  • 6번째 줄 : "Hello Qt"라는 문자열을 출력하는 QLabel 위젯을 생성하고 있다.
  • Qt와 유닉스에서 통용되는 위젯(Widget)이란 용어는 유저 인터페이스 상에 자리잡은 각각의 비주얼한 요소를 일컫는 말이다. '윈도우 가젯'이란 말에서 유래된 이 용어는, 윈도우에서 사용되는 용어인 '컨트롤'이나 '컨테이너'와 그 의미하는 바가 동일한데, 이를 테면 버튼, 메뉴, 스크롤 바, 프레임 등이 바로 위젯인 것이다. 하지만 Qt는 어떠한 위젯이라도 윈도우가 될 수 있다는 특징이 있다.
  • 7번째 줄 : 이 레이블이 화면에 보이게 만들고 있다. 모든 위젯은 항상 화면에 보이지 않는 상태로 생성되는데, 이러한 방침은 화면에 보이기 이전에 위젯에 필요한 모든 조치가 취해질 수 있게 하기 위한 것으로서, 이를 통해 불필요한 화면의  깜빡임을 막을 수 있게 된다.(화면 깜빡임의 다른 방법은 더블 버퍼링으로 5장에서 다룬다.)
  • 8번 줄 : 응용 프로그램의 제어를 Qt에게 넘겨주고 있다. 이렇게 되면 프로그램은 마우스 클릭이나 키보드 입력과 같은 사용자의 액션을 기다리는 일종의 대기모드인 이벤트 루프에 진입하게 된다. 사용자의 액션은 이벤트('메시지'라고도 함)를 발생시키게 되는데, 프로그램은 보통 이러한 이벤트에 대해 몇 가지 함수를 실행함으로써 반응하게 된다. 예를 들어, 사용자가 어떤 위젯을 클릭하면 '마우스 버튼의 누름'과 '마우스 버튼의 뗌'을 의미하는 이벤트가 생성된다.
  • main() 함수의 끝부분에서는 좀 더 간략함을 위해 QLabel 객체에 대한 delete 호출을 생략하고 있다. 프로그램이 종료되면 운영체제는 그 프로그램이 사용한 모든 메모리를 회수하기 때문에, 이 정도 크기의 작은 프로그램에서 발생하는 메모리 누수는 아무런 해가 되지 않는다.
  • 프로그램을 실행시키려면 먼저 컴퓨터에 Qt 4.3.2이상의 Qt 4가 설치되어 있어야 함.
  • 그리고 Qt의 bin 디렉토리가 PATH 환경변수에 설정되어 있어야 함.(부록 A 참조, 윈도우는 Qt 설치시 자동으로 등록됨.)
    • 1 # vi hello.cpp
      2 # qmake -project
      3 # qmake hello.pro
      4 # make
      5 # ./hello
    • 1 : chapter01의 hello 예제 파일 소스임.
    • 2 : 플랫폼에 독립적인 프로젝트 파일(hello.pro)이 생성됨.
    • 3 : 이전 단계에서 생성된 플랫폼 독립적인 프로젝트 파일로부터 특정 플랫폼을 위한 makefile이 생성됨.
    • 4 : 프로그램이 만들어 진다.
    • 5 : 만들어진 프로그램을 실행

 

  • ### 윈도우 비쥬얼 스튜디오 프로젝트 파일 만드는 법 ###
    • # qmake -tp vc hello.pro

 

 

(2) Signal / Slot

  • 시그널은 함수와 연결될 수 있어서, 시그널이 발생하면 그와 연결된 함수가 자동으로 실행되는데, 이처럼 시그널의 발생에 의해 자동으로 호출되는 함수를 슬롯이라고 한다.
  • SIGNAL()과 SLOT()은 시그널과 슬롯을 연결하는 데 사용하는 매크로이다.
  • ex) QObject::connect( button, SIGNAL(clicked()), &app, SLOT(quit()));

 

(3) Widget

  • QWidget은 어떤 응용프로그램의 메인 윈도우가 될 수 있다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         

 

 

(4) Reference Document

 

 

end

2010년 4월 19일 월요일

Qt4를 이용한 C++ GUI 프로그래밍-시작하기

* Qt(큐트)

  • 소스 코드 한 벌만으로 다양한 운영체제 환경에서 실행 가능한 어플리케이션을 만들 수 있도록 해주는 크로스 플랫폼 응용프로그램 프레임워크
  • 노르웨이에 있는 트롤테크에서 처음 개발되었고, 2008년 노키아가 인수하여 현재 모바일 및 데스크톱 소프트웨어에 관한 노키아의 플랫폼 소프트웨어 전략의 핵심 역할을 하고 있음.(2008년?)
  • Write Once, Compile Anywhere : 소스 코드는 한 벌만 만들고 이를 원하는 운영체제 환경에서 컴파일하기만 하면 해당 환경에서 실행될 수 있는 이미지가 만들어진다.(윈도우, 리눅스, 맥 OS 지원, 임베디드 리눅스, 윈도우 CE 지원)
  • Qt로 만들어진 제품들 : 구글 어스, 얻도비 포토샵 앨범, 스카이프, 메스메티카,  KDE, KOffice
  • 오픈 소스로 배포되고 있음

 

* Qt 라이선스

  • 오픈 소스 에디션
    • GNU GPL 사용에 대한 요구사항이 포함됨
    • 소스를 보고, 수정하고, 배포하는 권리를 부여함.
  • 상용 에디션
    • 만든 응용 프로그램을 상용 라이선스 조건을 적용하고자 할 경우 사용
    • 자신만의 조건 하에 판매하고 배포할 수 있음.

 

* Qt 설치하기(부록 A)

  • Qt 다운로드 하기
  • 책 예제 다운 받기
  • Qt/윈도우 설치(MinGW C++ 설치 필수)
  • Qt/맥 설치(Xcode Tools 먼저 설치 필수)
  • Qt/X11 설치
    • # cd /tmp
    • # gunzip qt-x11-opensource-src-4.3.2.tar.gz
    • # tar xvf qt-x11-opensource-src-4.3.2.tar
    • # cd /tmp/qt-x11-opensource-src-4.3.2
    • # ./configure
    • # make
    • # make install or sudo make install
    • 환경 변수 설정(.profile)
      PATH=/usr/local/Trolltech/Qt-4.3.2/bin:$PATH
      export PATH

 

2010년 4월 14일 수요일

linux 2.6 device model

* 5 component for device model

  • the device model core -> defines a set of structures and functions
    • 'include/linux/device.h', 'drivers/base/*.c'
  • the generic bus drivers
    • bus / struct bus_type / bus_register(), bus_unregister()
  • the bus  controller drivers
    • device / struct device / device_register(), device_unregister()
  • the device drivers
    • driver / sturce device_driver / driver_register(), driver_unregister()
  • the class drivers
    • class / struct class / class_register(), class_unregister()

 

* Device Model Core

  • 'struct bus_type' : Represents busses(PCI, USB, I2C, etc.)
  • 'struct device' : Represents devices(Intel AC97 audio controller, Intel PRO/100 ethernet controller, a PS/2 mouse, etc.)
  • 'struct device_driver' : Represents kernel drivers that handle devices
  • 'struct class ' : Represents a class of devices(sound, input, graphics, etc.)
  • 'include/linux/device.h', 'drivers/base/*.c'

 

* device_register() : 한 device에 대해 맞는 driver들을 검색

* driver_register() : 한 driver에 대해 맞는 device들을 검색

 

* Generic Bus Drivers

  • kernel이 지원하는 모든 bus마다 generic bus driver가 있다. Generic bus driver는 sturct bus_type을 allocate하고 bus_register()를 써서 kernel의 bus type list에 register한다.
  • bus_type structure
    • name (string)
    • !klist_devices (klist)
    • !klist_driver (klist)
    • match (fp)
    • suspend (fp)
    • resume (fp)
  • klist_devices는 이 bus에 존재하는 device들의 list, Bus controller driver가 device_register()를 호출함에 의해 update 됨.
  • Bus controller driver는 system initialization 시 bus를 scan해서 어떤 device들이 있는지 check한 뒤 각 device마다 device_register()를 호출해서 klist_devices를 scan해서 맞는 driver (match() 이용)를 찾는다. 그런 뒤 device를 klist_devices에 update한다.
  • Bus controller driver는 또한 gadget이 hot plugged 되었을 때(어떤 device인지 확인한 뒤) device_register()를 호출해서 klist_drivers를 scan해서 각 device 마다 맞는 driver( match() 이용 )를 찾는다. 그런뒤 device를 klist_devices에 update 한다.
  • klist_driver는 이 bus에 존재하는 device들을 handle할 수 있는 driver들의 list, Device driver가 스스로 initialization 할 때, driver_register()를 호출하여 자신을 등록함으로써 갱신된다.
  • Device Driver가 kernel에 inserted 되면, 이 driver는 driver_register()를 호출하여 해당 bus에 대해 klist_devices를 scan하여 이 driver가 다룰 수 있는 device들을 찾는다. 그런 뒤 driver를 klist_drivers에 update 한다.
  • match()에 의해 device와 driver가 associated 되는 것을 binding이라고 한다.
  • ex) 'drivers/net/phy/mdio_bus.c'
  • struct bus_type mdio_bus_type = {
    . name = "mdio_bus",
    .match = mdio_bus_match,
    .suspend = mdio_bus_suspend,
    .resume = mdio_bus_resume,
    };

 

* '!' is internal to the device motel core and should not be touched by the bus controller driver directly.

 

* Bus Controller Drivers

  • Bus의 device driver다. 따라서, 여느 device drivers와 마찬가지로 자신을 driver_register()로 등록함. 그러나 추가적으로 자신이 다루는 bus 상에 있는 devices를 detect하여 device_register()를 이용해 등록한다. bus_type 구조체의 klist_devices list에.
  • 새로운 Linux device driver model에서 모든 device는 bus 상에 존재하므로, 결국 bus controller driver가 모든 device를 등록한다. struct device 형태로. bus_type 구조체의 klist_devices list에.
  • device
    • bus_id (string)
    • bus (bus_type)
    • parent (device)
    • !driver(device_driver)
  • 'drivers/net/gianfar_mii.c'

 

* Device Drivers

  • 모든 device driver는, driver_register()를 호출해 bus_type 구조체의 klist_driver list에 자기 자신을 등록한다. 그 다음에 device model core가 이 driver를 한 device와 binding을 시도함.
  • 한 device가 registered 되면 (이는 곧 이 device를 handle할 수 있는 drivers가 klist_drivers에 등록된다는 말이므로) 한 특정 driver에 의해 handled 될 수 있는데, 그 driver의 probe member가 하는 일이 바로 그 특정 device 하나를 위해 이 driver의 한 instance를 생성해내는 (그리고 그 device를 초기화하는) 일이다.
  • device_driver
    • bus (bus_type)
    • probe (fp)
    • remove (fp)
    • suspend (fp)
    • resume (fp)
  • bus는 이 driver가 등록될 klist_drivers를 가진 bus_type 구조체에 대한 pointer.
  • probe는, 이 driver가 지원하는 device가 detected (이는 곧 device를 지원하는 drivers를 klist_drivers에서 찾아내는 일을 한 것 즉, binded) 될 때마다 불리는 callback function. 이 함수는 driver 자신을 각 device 당 하나 씩 instantiate한 뒤 그 device를 initialize 한다.
  • remove는 이 driver를 그 device로부터 unbind하기 위해 불리는 callback function. Unbinding은 device가 physically removed 되거나 driver가 unloaded 되거나 system이 shutdown 될 때 일어난다.
  • 'drivers/net/phy/'

 

* Class Drivers

  • Class driver는 그것이 표현하는 device class들에 대해 struct class를 instantiate하여  class_register()를 통해 device model core에 등록한다.
  • Devices를 적당한 class에 추가하는 것은 각 해당 device driver의 책임이다.
  • class
    • name (string)
    • !devices (list)
  • devices는 이 class에 속한 device들의 list이다. 이 list는 device driver들에 의해 갱신된다. (그 device driver들이 자기 자신들을 각 device들에 대해 instantiate할 때).

 

* Conclusion

  • 결국 이런 data structure들이 있음으로 해서, device들이 어떻게 tree 구조를 이루고 있는지 알 수 있고, 어떤 종류의 device들이 system에 존재하는지도 알 수 있다.
  • 그 효과는 더 나은 power management, 그리고 system에 연결된 devices에 대한 더 나은 통찰.

 

출처 : 블로그

 

 

I2C

I2C(Inter-Integrated Circuit,아이 스퀘어 씨)

  • 필립스에서 개발한 직렬 컴퓨터 버스
  • 마더보드, 임베디드 시스템, 휴대전화 등에 저속의 주변 기기를 연결하기 위해 사용됨.
  • I2C는 풀업 저항이 연결된 직렬 데이터(SDA)와 직렬 클럭(SCL)이라는 두 개의 양방향 오픈 컬렉터 라인을 사용한다. 최대 전압은 +5V이며, 일반적으로 +3.3V 시스템이 사용되지만 다른 전압도 가능하다.
  • I2C 레퍼런스 디자인은 7bit의 주소 공간을 가지며, 이 중 16개는 예약되어 있으므로, 동일한 버스에 최대 112개의 노드를 연결할 수 있다. 가장 일반적으로 사용되는 I2C 버스의 모드는 표준 모드인 100kbit/s와 저속 모드인 10kbit/s가 사용된다. 최신 리비전의 I2C는 보다 빠르게 동작하며, fast mode인 400kbit/s와 고속 모드인 3.4Mbit/s를 지원한다. 최대 1008 노드까지 연결 가능한 10bit 주소 지정 등의 확장된 기능등을 지원한다.
  • 응용 영역
    • 사용자 설정값을 저장하기 위해 NVRAM에 접근하는 경우
    • 저속의 디지털-아날로그 변환 회로에 접근하는 경우
    • 저속의 아날로그-디지털 변환 회로에 접근하는 경우
    • 모니터의 명암, 대비, 색상 등을 변경하는 경우
    • 지능형 스피커의 볼륨값을 변경하는 경우
    • 휴대전화 같은 장치에 포함된 발광 다이오드를 제어하는 경우
    • 중앙 처리 장치 온도나 팬 속도와 같은 하드웨어 모니터링 정보나 진단 센서 정보를 읽는 경우
    • 실시간 클럭 값을 읽는 경우
    • 시스템 요소의 전원을 제어하는 경우
  • I2C의 장점은 특히 마이크로컨트롤러에서 단지 2개의 일반 목적 입출력 핀(GPIO)과 소프트웨어만을 이용하여 여러 장치들을 제어할 수 있다는 점이다
  • 주변장치들은 시스템이 동작 중일 때도 I2C 버스에 추가/제거될 수 있으며, 이것은 핫 스왑이 필요한 요소들을 이용하는 응용에 적합하다.
  • I2C는 엑세스 버스, VESA 디스플레이 데이터 채널 (DDC) 인터페이스, 시스템 과리 버스(SMBus), IPMI 프로토콜 중의 하나인 지능형 플랫폼 관리 버스(IPMB)의 기본 기술이다. 이러한 것들은 전압과 클럭 주파수 범위에서 차이가 있으며, 인터럽트 라인을 가질 수 있다.
  • I2C 버스의 설계상 장점 : 노이즈에 강하여 신뢰성이 높고, 매우 적은 전력을 사용하며, 다양한 온다환경에서도 잘 동작할 뿐만 아니라, 다양한 전압레벨을 지원한다.

 

* I2C에서 ACK의 역할

  • Write 시 정상 수신 신호
  • Read 시 송신 완료 신호
  • Write, Read 모두 ACK 신호는 Slave에서 발생시킴

 

* I2C의 정의

  • 1980년대 필립스에서 개발된 버스 표준안
  • 2개의 전송 라인을 이용한 양방향 통신 지원(SDA, SCL)
  • 현재 세계에서 가장 많이 쓰이는 임베디드 표준안
  • Multi-master capable bus with arbitration feature
  • Master-Slave communication supported
  • Each IC on the bus is identified by its own address code

 

* I2C의 장점

  • 단순한 하드웨어 구성
  • 단순한 프로토콜로 구성
  • 장치의 연결과 제거가 용이함
  • Simpler PCB
  • Fast enough for all "Human Interfaces" applications(Display, Switches, Keyboard)
  • Large number of I2C devices

 

* I2C Signals

 (1) Control Signal

  • SCL highdptj SDA transition으로 판정
  • Start / Stop bit
    • Start : SDA low 이동 후 SCL low 이동
    • Stop : SCL high 이동 후 SDA high 이동

 (2) Data Signal

  • SCL이 pulse 안에서 SDA 데이터의 이동으로 0/1 구분
  • SCL pulse 안에서...
    • SDA pulse 존재하면 : 1
    • SDA pulse 존재하지 않으면 : 0

 (3) ACK / NAK Signal

  • 9번째 data 신호로 판명
    • ACK : 0
    • NAK : 1

 

 

The image shows a simplified equivalent circuit diagram for an I2C connection between two devices (master or slave). It shows all factors which are relevant for I2C.

 

VCC I2C supply voltage, typically ranging from 1.2 V to 5.5 V
GND Common ground
SDA Serial data (I2C data line)
SCL Serial clock (I2C clock line)
Rp Pull-up resistance (a.k.a. I2C termination)
Rs Serial resistance
Cp Wire capacitance
Cc Cross channel capacitance

 

 

출처 : 위키 백과, 다음 블로그, 네이버 블로그, I2C bus(영문)

2010년 4월 13일 화요일

latency

latency : 지연 (또는 대기) 시간

 

1. 네트워크에서의 latency는 delay와 비슷한 말로서, 하나의 데이터 패킷을 한 지점에서 다른 지점으로 보내는데 소요되는 시간을 표현한 것이다. 그러나 일부에서는 (예를 들어 AT&T 등에서는), 패킷 하나를 보내고 그것이 송신자에게 되돌아올 때까지의 왕복에 걸리는 시간을 latency라고 부르기도 한다. latency는 한 지점에서 다른 지점 사이에 (지연시간이 전혀 없이) 데이터가 즉시 전송되어야만 하는 것으로 가정한다. 네트워크에서 latency를 일으키는 요인은 다음과 같다.

  • 전달 지연 : 이것은 단순히 하나의 패킷이 한 지점에서 다른 지점으로 광속으로 이동하는데 걸리는 시간이다.
  • 전송 지연 : (광케이블, 무선 또는 그 밖의 어떤 것이라도) 매체 그 차제에서 약간의 지연이 생긴다. 또 패킷의 크기에 따라서도 왕복하는데 지연이 생길 수 있는데, 그 이유는 패킷이 클수록 수신하고 반환하는데 시간이 더 걸리기 때문이다.
  • 라우터 및 기타 처리 지연 :  게이트웨이 노드들 시험하고, 또 어쩌면 패킷 내의 헤더를 변경 (예를 들어, TTL 필드 내에 있는  카운트의 값을 변경하는 등) 하는 데에도 시간이 걸린다.
  • 다른 컴퓨터 및 저장장치 지연 : 네트웍 내 행로 양단에서, 패킷은 스위치 브리지와 같은 중간 장비들에서 하드디스크와 같은 저장장치에 액세스하기 쉽다 (그러나백본 통계에서, 이러한 종류의 지연은 십중팔구 고려되지 않는다). 

 

2. 컴퓨터 시스템에서의 latency는 종종 응답시간을 늦추는 지연이나 대기를 의미하는데 사용된다. 컴퓨터 latency에 기여하는 명확한 요인들로는, 마이크로프로세서와 입출력장치들 간의 데이터 속도가 맞지 않거나, 데이터 버퍼링이 불충분한 것 등이 포함된다. 컴퓨터 내에서, latnecy는 prefeching이나 멀티 스레딩, 또는 다중 스레드의 실행에 걸친 병렬 처리의 사용 등

과 같은 기술에 의해 제거되거나 감추어질 수 있다.

 

3. 입체 시야와 머리 추적 장치 등이 제공되는 헬멧을 설명하는 3차원 모의실험에서, latency는 컴퓨터가 머리의 움직임을 감지하는 때부터 적절한 이미지가 나타나는데 까지 걸리는 시간을 말한다.

 

출처 : 텀즈

2010년 4월 10일 토요일

리눅스 사운드 프로그래밍

< 음악이 생겨라 (Let There Be Music) >

 

by Shuveb Hussain

한글 번역 전정호

이 글은 한글번역판을 요약한 것입니다.

 

*** 사운드 카드 프로그래밍 ***

 

 (1) 샘플링

  • 음을 녹음할 때 음질을 선택한다.
  • 음질을 결정하는 중요한 요소 중 하나가 샘플링 빈도(sampling rate)이다.
  • 음은 시간에 따라 진동수가 바뀌는 파장일 뿐이다.
  • 음을 녹음하려면 일정 간격으로 음의 진동수를 기록한다. 이 간격을 샘플링 빈도라고 한다.
  • 샘플링 빈도가 높을수록 음질이 좋아진다. 예를 들어, CD의 샘플링 빈도는 초당 44100번, 즉 44.1kHz이다.
  • PCM(Pulse Code Modulation, 펄스 코드 변조)이라고 하는 이 작업은 ADC(Analogue to Digital Converter, 아날로그-디지털 변환기)가 한다.

 

 

 (2) 비트와 채널

  • 음을 샘플링할 때, 샘플당 일정 수의 비트를 사용하고, 이런 채널을 여러 개 사용한다. 샘플링하는 자료의 비트 개수를 샘플링 정밀도(resolution)라고 한다.
  • 가장 흔한 형식은 8비트 양수 바이트 혹은 16비트이다.
  • 채널별로 자료를 분리한다. 예를 들어, CD 음악에는 왼쪽, 오른쪽(스테레오) 두 채널이 있다.
  • 8비트 정밀도로 CD음질을 녹음할 때 초당 필요한 크기를 계산해보면 :
  •        2        x       44100      =      88200 bytes
    (채널 개수) x (샘플링 빈도) = (초당 필요한 크기)

  • 이제 이론은 충분하니 실제 프로그램을 시작하자.

 

 

 (3) 사운드 카드를 프로그래밍 하기

  • 사운드 카드를 프로그래밍하는 방법이 몇가지 있다.
  •  초기 리눅스 드라이버가 만들어지던 때 두 그룹이 있었다.
    • Open Sound System(OSS)은 많은 장치 드라이버를 작성한 그룹으로 심지어 하드웨어 사양을 공개하지 않거나 비밀유지동의(non-disclusure agreement)를 하지않은 개발자에게 사양을 공개하지 않는 사운드 카드 제조사의 이진모듈도 포함하였다. 하드웨어 제조자가 개인에게 사양을 알려주려고하지 않았기 때문에 OSS는 4Front Technologies란 회사를 만들었다.
    • ALSA(Advanced Linux Sound Architecture)는 제조사가 사양을 공개한 사운드 카드 드라이버만 작성했다. ALSA는 2.6-test 커널에 포함되어 있다.
  • ALSA는 OSS 에뮬레이션 계층을 제공하기 때문에 OSS로 작성한 프로그램은 OSS와 ALSA 시스템에서 모두 동작한다. 간단하고 대다수의 시스템에 설치되어 있기 때문에 이 글은 OSS 프로그래밍을 다룰 것이다.

 

  • 유닉스/리눅스는 모든 장치 드라이버마다 (보통 /dev 디렉토리에) 파일 시스템 인터페이스가 있다. 이 장치파일을 open, read, write, lseek, close와 같은 파일관련 시스템 호출에 사용한다. 장치파일을 장치드라이버가 요청을 기다리는 파일시스템상의 훅(hook)이라고 보면 된다.예를 들어, /dev/hda1 파일은 primary master IDE 하드디스크의 첫번째 파티션에 대한 인터페이스이다. open 시스템호출을 사용하여 파일을 열면 일반파일과 같이 파일핸드(file handle)을 얻을 수 있다. 파일핸들을 읽으면 실제로 파티션의 첫번째 섹터에 있는 자료를 읽게 된다. 또, 앞으로 lseek하면 파일포인터(file pointer)를 앞으로 이동한다. 섹터를 건너뛰으려면 섹터 크기만큼 앞으로 lseek한다. 위험하므로 하드디스크 장치 파일을 수정하지는 마라. 파티션에 값을 쓰면 파티션이 망가질 수 있다. 하드웨어 장치는 보통 root만 직접 접근할 수 있다.

 (4) 코드

  • 이제 코드로 넘어가자. 이 코드는 root가 아니어도 문제없이 실행되야 한다. 파일장치를 접근하는데 문제가 있다면 root로 su하고 chmod하여 접근 권한을 푼다. 물론 리눅스에서 작동하는 사운드카드를 사용해야 한다. 직접 코드를 입력하지 않고 여기에서 다운받을 수 있다. demo.pcm 파일도 같이 다운받아야 한다.

 

/*
 * oss.c는 사운드카드에서 raw PCM 22KHz 샘플음을 낸다
 *
 * 중요 - 프로그램을 실행하기전에 현재 디렉토리에 demo.pcm 파일이 있는지 확인하라.
 */

#include < sys/types.h >
#include < sys/stat.h >
#include < sys/soundcard.h >
#include < sys/ioctl.h >
#include < unistd.h >
#include < fcntl.h >
#include < errno.h >
#include < stdlib.h >

#define SECONDS 5 //재생 시간 (초)

int main()
{
    int fd;
    int handle = -1;
    int channels = 1;         // 0=모노 1=스테레오
    int format = AFMT_U8;
    int rate = 22000;
    unsigned char* data;

   /* 사운드카드에 해당하는 파일에 쓰기위해(write) 파일을 연다(open). DSP = Digital Signal Processor */
    if ( (handle = open("/dev/dsp",O_WRONLY)) == -1 )
    {
  perror("open /dev/dsp");
  return -1;
    }

   /* 재생하려는 음이 스테레오라고 사운드카드에 알린다. 0=모노 1=스테레오 */
    if ( ioctl(handle, SNDCTL_DSP_STEREO,&channels) == -1 )
    {
  perror("ioctl stereo");
  return errno;
    }

    /* 자료 형식을 사운드카드에게 알린다 */
    if ( ioctl(handle, SNDCTL_DSP_SETFMT,&format) == -1 )
    {
  perror("ioctl format");
  return errno;
    }

    /* DSP 재생율(playback rate), 즉 raw PCM 음의 샘플링 빈도를 지정한다. */
    if (ioctl(handle, SNDCTL_DSP_SPEED,&rate) == -1 )
    {
  perror("ioctl sample rate");
  return errno;
    }

    // 빈도 * 5 초 * 두 채널
    data = malloc(rate*SECONDS*(channels+1));

    if((fd=open("demo.pcm",O_RDONLY))==-1)
    {
  perror("open file");
  exit(-1);
    }

    /* demo 파일에 저장된 정보를 읽어서 할당한 메모리에 저장한다 */
    read(fd,data,rate*SECONDS*(channels+1));
    close(fd);

    /* 읽은 내용을 사운드카드에 쓴다(write)! 그러면 재생이 된다. */
    write(handle, data, rate*SECONDS*(channels+1));

    if (ioctl(handle, SNDCTL_DSP_SYNC) == -1)
    {
  perror("ioctl sync");
  return errno;
     }

    free(data); //좋다. 마무리.
    close(handle);

    printf("===Done===\n");
    return 0;
}


 

(5) 코드 설명

  • 이 프로그램은 raw PCM, 22KHz, stereo 자료파일을 5초간 연주한다. 프로그램은 크게 3가지 작업을 한다.
    • sound 장치 열기(open)
    • 재생을 위한 파라미터 설정
    • 장치에 자료 쓰기(write)
  • open() / write() / close() 시스템 호출은 일반 파일과 동일하다.
  • ioctl()(Input/Output ConTroL) 시스템 호출을 사용하여 재생에 사용할 파라미터를 설정한다. ioctl() 시스템 호출은 입출력 장치와 통신하거나 파라미터를 설정할 때 사용한다. 또 시스템 호출의 개수를 줄이기 위한 편법으로 사용되기도 한다. 그래서 흔히 프로그래머의 다용도칼이라고 부른다. 함수의 원형
  • int ioctl( int fd, int command, ... );

    • fd : 장치의 파일 기술자(file descriptor)
    • command : 장치에 대한 요청/명령
    • ... : command에 따라 달라진다.
  • ioctl(handle, SNDCTL_DSP_SPEED, &rate)
    • DSP 재생을 설정한다. rate는 장치 드라이버로 전달되는 실제 재생율이다.
  • 예제 프로그램에는 3가지 ioctl()이 있다.
    • 재생에 사용할 채널 개수(channels)를 설정
    • PCM 형식(format)을 설정
    • 재생율(sampling rate)을 설정
  • 이것으로 장치에 필요한 정보는 충분하고, 다음은 장치파일에 PCM 자료를 직접 쓰면(write) 재생이 된다. 마지막 ioctl()은 장치를 비우고(flush), 그 다음 PCM 자료를 저장하기 위해 할당한 메모리를 해제한다. 이게 끝이다.

 

 

(6) 음악 저장 형식

  • 방금 전에 5초짜리 22KHz 음악을 재생하기 위해 raw PCM 자료 220KB가 필요했다.
    • 22,000 x  5  x   2    = 220,000 bytes
    • (샘플   x 초 x 채널 = 데이터 크기)
    • CD 음질로 1분을 재생하기 위해 필요한 크기는 :
      • 44,100 x 60 x 2 = 5292000 bytes, 약 5 MB!
  • 음악 CD는 raw PCM 형식으로 자료를 저장한다. 그러나 컴퓨터는 음악을 효율적으로 저장하고 (인터넷으로) 전송하기 위해 음악을 압축하여 크기를 줄이고 재생시 다시 압축을 푼다. 어떤 음악이던 관계없이 샘플링률은 고정되어 있다. 아무 소리가 없는 몇 초간을 샘플링 했다고 생각해 보자. 같은 시간의 시끄러운 락 음악과 동일한 크기가 필요하다.
  • raw 음악파일은 자료반복이 매우 적기 때문에 일반적인 압축방법으로는 잘 압축되지 않는다. 음악은 다른 기술을 사용하여 압축한다. 가장 일반적인 방법은 사림이 귀로 들을 수 없는 부분을 제거하거나 음악 특성에 따라 압축한다. 음악을 좋아하는 사람들에게 가장 대중적인 형식은 분명 MP3다. 현재 MP3에는 특허문제가 걸려 있기 때문에, 오픈소스 공동체에서는 Ogg Vorbis 형식을 반긴다. 두 형식 모두 크기가 비슷하게 줄어들며 음질의 손실을 최소화한다.

 

 

 (7) Ogg Vorbis 파일을 재생하는 방법

  • 사운드 카드가 어떻게 raw 음악 자료를 재생하는지 알았으니, Ogg Vorbis 파일을 재생하는 방법을 알아보자. Ogg Vorbis 파일을 재생하려면 먼저 복호화(decode), 즉 raw PCM 자료로 변환해야 한다.
  • libvorbisfile이 이 작업을 한다. 이 라이브러리는 매우 낮은 수준을 다루지만 더 세밀한 조절이 가능한 libvorbis 라이브러리보다 높은 수준에서 변환을 한다. 이제 문제가 간단해진다 : Ogg Vorbis 파일에서 읽은 자료를 라이브러리로 넘기고, 라이브러리가 변환된 raw PCM 자료를 사운드 카드로 직접 보낸다. 소스는 여기에
  • #include < sys/types.h >
    #include < sys/stat.h >
    #include < sys/soundcard.h >
    #include < sys/ioctl.h >
    #include < unistd.h >
    #include < fcntl.h >
    #include < errno.h >
    #include < stdlib.h >

    #include "vorbis/codec.h"
    #include "vorbisfile.h"

    int setup_dsp(int fd,int rate, int channels);

    char pcmout[4096]; // 변환한 PCM 자료를 저장할 4KB 버퍼
    int dev_fd;

    int main(int argc, char **argv)
    {
     OggVorbis_File vf;
     int eof=0;
     int current_section;
     FILE *infile,*outfile;

     if(argc<2)
     {
      printf("supply file arguement");
      exit(0);
     }

     if ( (dev_fd = open("/dev/dsp",O_WRONLY)) == -1 )
    {
      perror("open /dev/dsp");
      return -1;
     }

     infile=fopen(argv[1],"r");

     if(infile==NULL)
     {
      perror("fopen");
      exit(-1);
     }  

    if(ov_open(infile, &vf, NULL, 0) < 0)
    {
      fprintf(stderr,"Input does not appear to be an Ogg bitstream.");
      exit(1);
     }

     char **ptr=ov_comment(&vf,-1)->user_comments;
     vorbis_info *vi=ov_info(&vf,-1);

     while(*ptr)
     {
      fprintf(stderr,"%s",*ptr);
      ++ptr;
     }

     fprintf(stderr,"Bitstream is %d channel, %ldHz",vi->channels,vi->rate);
     fprintf(stderr,"Decoded length: %ld samples",(long)ov_pcm_total(&vf,-1));
     fprintf(stderr,"Encoded by: %s",ov_comment(&vf,-1)->vendor);

     if(setup_dsp(dev_fd,vi->rate,vi->channels-1))
     {
      printf("dsp setup error.aborting");
      exit(-1);
     }

     int count=0;

     while(!eof)
     {
          long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,&current_section);
          if (ret == 0)
          {
        /* EOF */
      eof=1;
          }
          else if (ret < 0)
          {
            /* 자료에 오류가 있다.  (프로그램에) 중요하다면 보고하지만,
      이 프로그램은 하지 않는다. */
           }
          else   {
      printf("Writing %d bytes for the %d time.",ret,++count);
      write(dev_fd,pcmout,ret);
          }
     }

     ov_clear(&vf);
     fclose(infile);
     
    if (ioctl(dev_fd, SNDCTL_DSP_SYNC) == -1)
    {
          perror("ioctl sync");
      return errno;
     }

     close(dev_fd);
     fprintf(stderr,"Done.");

     return(0);
    }


    int setup_dsp(int handle,int rate, int channels)
    {
        int format;

        if ( ioctl(handle, SNDCTL_DSP_STEREO,&channels) == -1 )
        {
      perror("ioctl stereo");
      return errno;
        }

         format=AFMT_U8;

         if ( ioctl(handle, SNDCTL_DSP_SETFMT,&format) == -1 )
        {
      perror("ioctl format");
      return errno;
        }
     
        if ( ioctl(handle, SNDCTL_DSP_SPEED,&rate) == -1 )
       {
      perror("ioctl sample rate");
      return errno;
        }

         return 0;
    }

 

  • 다음과 같이 컴파일 한다.
  • gcc oggplay.c -oggplay -lvorbisfile -I/path/to/vorbis/header/files -L/path/to/vorbis/lib/files

  • 라이브러리파일과 헤더파일이 /usr/lib 이나 /usr/include 같은 일반적인 위치에 있다면 -l 과 -L 명령행 옵션이 필요없다. 모든 대중적인 배포본에 vorbisfile 라이브러리가 포함되있다. 만약 시스템에 설치가 안되있다면 여기에서 다운받을 수 있다. 또, Ogg Vorbis 사이트는 여기다. 프로그램을 컴파일하려면 (개발용) 헤더파일이 필요하다.

  • setup_dsp 함수는 dsp 장치를 열고(open), 세가지 중요한 파라미터인 채널, 형식, 재생율을 지정한다. 음악 재생을 위해 가장 중요한 세가지 파라미터를 기억하라. main 함수는 오류검사외에, 쉘 아규먼트로 준 Ogg Vorbis 파일을 열고, 파일에 저장된 설명과 파일정보를 출력한다. ov_open() 라이브러리함수가 채우는 구조체에 저장된 샘플링 빈도와 채널 정보를 setup_dsp 함수에 넘긴다. 그후 프로그램은 Ogg Vorbis 파일 내용을 변환하여 버퍼에 넣는 반복문을 실행한다. 반복문은 버퍼에 저장한 raw PCM 자료를 앞에서 설정한 dsp 장치에 쓴다. 파일이 끝날때까지 반복한 후, 마지막으로 정리하고 종료한다. 간단하지 않는가? 쉽고 직관적으로 변환해준 libvorbisfile에게 감사하다.
  • Ogg Vorbis 파일을 변환하려면 libvorbisfile을 사용하면 된다. MP3 파일을 변환하여 재생하고 싶다면 여러 라이브러리를 선택할 수 있다. 많이 사용하는 라이브러리중에 영상과 음악을 모두 변환할 수 있는 smpeg 라이브러리가 있다. 또, libmad 라이브러리도 찾았다. 나는 smpeg의 음악 변환 기능만 사용하기로 했다. 관심이 있다면 smpeg의 MPEG 영상 변환 기능도 살펴보길 바란다. 라이브러리 사용법을 설명하는 샘플 프로그램 plaympeg도 포함되있다. 영상을 보여주기위해 smpeg은 매우 사용하기 쉽고 기능이 많은 그래픽 프로그래밍 라이브러리인 SDL을 사용한다. 이외에도 MP3를 변환하는 라이브러리는 많지만, 많은 리눅스 배포본에 smpeg이 포함되있기때문에 smpeg을 선택했다. 많이 사용하는 gtv MPEG 영상플레이어도 smpeg 패키지에 포함되있다.

 

 (8) MP3 파일 연주하는 프로그램 예제

  • smpeg 라이브러리가 변환한 MP3 자료를 직접 사운드 카드로 보낸다. 직접 PCM을 다룰 필요가 없다. 소스 다운로드
  • #include < stdio.h >
    #include < stdlib.h >
    #include < string.h >
    #include < signal.h >
    #include < unistd.h >
    #include < errno.h >
    #include < sys/types.h >
    #include < sys/stat.h >
    #include < sys/ioctl.h >
    #include < sys/time.h >

    #include "smpeg.h"

    void usage(char *argv0)
    {
        printf("Hi,%s This is the normal useage.",argv0);
    }

    int main(int argc, char *argv[])
    {

        int volume;
        SMPEG *mpeg;
        SMPEG_Info info;
       
        volume = 100; //Volume level

        /* 아규먼트가 없으면 사용법만 출력한다 */
        if (argc == 1)
        {
             usage(argv[0]);
             return(0);
        }

        mpeg = SMPEG_new(argv[1], &info;, 1);

        if ( SMPEG_error(mpeg) )
        {
                fprintf(stderr, "%s: %s", argv[1], SMPEG_error(mpeg));
                SMPEG_delete(mpeg);
        }

        SMPEG_enableaudio(mpeg, 1);
       SMPEG_setvolume(mpeg, volume);

        /* 음악에 대한 정보를 출력한다 */
        if ( info.has_audio )
        {
                printf("%s: MPEG audio stream", argv[1]);
         
                if ( info.has_audio )
                    printf("Audio %s", info.audio_string);

                 if ( info.total_size )
      printf("Size: %d", info.total_size);
             

                  if ( info.total_time )
      printf("Total time: %f", info.total_time);

                   /* 재생하고 재생이 끌날때까지 기다린다 */
      SMPEG_play(mpeg);  

      while(SMPEG_status(mpeg)==SMPEG_PLAYING);

            SMPEG_delete(mpeg); //구조체 반환
       }

       return(0);
    }

  • 여기에 있는 smpeg을 설치한후 프로그램을 컴파일한다. smpeg을 설치하기위해서 미리 SDL을 설치해야 한다. 컴파일할때 헤더파일과 라이브러리파일 경로를 컴파일러에게 알려줘야 한다. 쉽게 하려고 smpeg 패키지는 smpeg-config라는 간단한 도구를 제공한다. 다음과 같이 프로그램을 컴파일한다:
  • gcc playmp3.c `smpeg-config --cflags --libs` -I/usr/include/SDL

  • smpeg-config 명령어를 감싸는 따옴표문자를 주의하라. 보통 backqoute라고 부르며, US식 키보드에서 틸데(~) 문자와 같이 있다. 쉘에서 이 문자는 안에 있는 명령어의 출력을 그 자리에 대신한다. 그냥 smpeg-config 명령만 실행해보면 내가 무슨 말을 하는지 알 것이다. -I/usr/include/SDL 명령행 옵션을 -I < 실제 SDL 경로 >로 수정하라. SDL 함수를 사용하지 않아도, smpeg.h가 내부적으로 SDL 헤더파일을 사용하므로 SDL 헤더파일 경로를 지정해야 한다. RPM 사용자는 프로그램을 컴파일하기위해 smpeg과 smpeg-devel 패키지를 설치해야 한다.
  • SMPEG_new 라이브러리함수는 필요한 내부 객체를 할당하고, MP3 파일에 대한 정보를 SMPEG_info 구조체에 채운다. 프로그램은 이 정보를 출력하고, SMPEG_play를 호출하여 재생을 시작한다. 함수는 즉시 반환되기때문에 다른 작업을 하면서 MP3를 연주하는 프로그램에 유용하다. 이 프로그램에서는 따로 할 일이 없기때문에 재생이 끝날 때까지 기다린다. SMPEG_delete는 그동안 라이브러리가 할당한 모든 메모리를 반환하고, 마친다

 

 글이 여러분의 프로그래밍 작업에 조금이나마 도움이 되길 바란다. 의견을 듣고 싶다. 잘못된 점을 알려주거나 제안을 바란다. shuveb@shuvebhussain.org로 내게 연락할 수 있다.

 

참고로 테스트를 해봤는데 PCM RAW파일로만 가능한다. ^^ 형식이 그렇네. mp3나 다른 형식의 파일을 받아서 cool edit로 변환해 주었다. 쿠울~~~ 에디터 ㄱㄱ 그리고 역시나 속도 그런거 잘 맞춰줘야 한다는 ^^

 

출처 : http://www.whiterabbitpress.com/lg/issue97tag/shuveb.html

 

출처 : 한국어 출처, 원문(영어)

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한 버퍼 내의 영상 데이터를 원하는 목적으로 처리한다. 이 과정에서 화면에 영상을 표시할 수 있다.
  • 더 자세한 내용은 출처를 참고한다.

 

 

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

전역변수에 왜 static을 사용했을까?

  • 전역변수에서의 static은 해당하는 파일 내에서만 사용한다는 의미를 가지고 있다.
  • 여러 개의 파일로 개발할 때에 유용한다.
  • a.c라는 파일과 b.c라는 파일에 똑같이 전역변수를 정의할 경우, c.c라는 파일에서 해당하는 전역변수를 사용하려 할 때 어느 쪽을 사용해야 할지 헷갈리게 된다. 아마도 링크 시에 에러가 날 것이다.
  • 전역변수를 static으로 정의하면 그 파일 내에서만 사용할 수 있으므로 외부에서는 변수에 접근을 못한다. 이로 인해 디버깅의 노력을 줄일 수 있다.
  • 완전히 외부 모듈에 공개할 것만 일반적인 전역변수로 잡고 나머지 모듈 내에서 사용할 것은 모두 static으로 선언하면 static 변수를 누가 바꿨는지 추적하기 위해 모든 소스를 뒤질 필요가 없다.

출처 : 네이버 지식in

inline 함수

< inline 함수 >

- 매크로 함수와 그냥 함수의 중간적인 성격을 띈 함수이다.

 

* 사용 이유

  • 일반적인 함수를 사용하면 필요할 때마다 호출하여 사용하므로 실행파일의 크기를 줄일 수 있으나 제어권의 이동이 심하므로 실행 속도가 느려진다.
  • 매크로 함수는 컴파일시 전개되어 치환되므로 제어권 이동이 발생하지 않으므로 속도가 빠르지만 데이터형 지정을 할 수가 없고 실행파일의 용량이 커지게 된다.
  • 인라인 함수는 컴파일시 통째로 매크로처럼 전개되어 속도면에서 큰 이득을 얻는다. 그리고 데이터형 체크를 할 수 있다. 용량이 커지는 단점이 있긴 하지만 간단한 작업을 하는 함수의 경우에 이용하면 매우 편리하다.

* 장점

  • function call이 생략되는 형태로 실행되기 때문에 function call에 의한 여러가지 오버헤드(CPU register 백업, stack 관리 등)를 생략하기 때문에 간단하면서 자주 사용되는 함수에는 더 빠른 효율성을 갖게 된다.

*단점

  • 지나친 inline 함수의 사용은 실행파일이 커지게 하고, 이 때문에 페이지 폴트를 야기하는 원인이 되어 퍼포먼스가 떨어지게 되기도 한다.

* 매크로 함수와 인라인 함수의 차이점

  • 안정성 측면에서 inline 함수가 앞선다.

* inline 함수의 제약조건

  • inline 함수 내에서는 루프문(do while, while, for), switch, goto문을 사용할 수 없다.
  • inline 함수 호출시 호출되기 전에 먼저 inline 함수가 정의되어 있어야 한다.
  • inline 함수 내에서 재귀호출을 할 수 없다.
  • inline 함수는 한 수식 내에서 두 번이상 호출될 수 없다.
  • 함수 포인터로 inline 함수의 주소를 취할 수 없다.
  • inline 함수는 호출방식이 아니라 치환전개방식이기 때문이다.

 

출처

2010년 4월 3일 토요일

pthread 사용하기

< pthread 사용하기 >

1. 기본 쓰레드 함수

(1) pthreard_create
  • 쓰레드 생성을 위해 사용(pthread_t)
  • 첫번째 인자는 쓰레드 식별자
  • 세번째 인자는 쓰레드 실행시 호출되는 함수
  • 네번째 인자는 그 함수의 인자
  • 리턴값은 쓰레드 ID
  • 실행된 쓰레드에 대해서는 pthread_join 등의 함수를 이용해서 쓰레드 종료 때까지 기다려줘야 한다. pthread_join은 일종의 fork의 wait와 비슷하게 동작하며, 쓰레드 자원을 해제시켜 준다.
  • ex) thr_id = pthread_create(&p_thread[1], NULL, t_function, (void *)&a);
(2) pthread_join
  • 첫번째 인자는 기다릴(join)할 쓰레드 식별자
  • 두번째 인자는 쓰레드의 return값
  • 두번째 인자가 NULL이 아닐 경우 해당 포인터로 쓰레드 return값을 받아올 수 있다.
  • ex) pthread_join(p_thread, (void *)&status);

(3) pthread_detach
  • detach는 "떼어내다"라는 뜻을 가지며, main 쓰레드에서 pthread_create를 이용해 생성된 쓰레드를 분리시킨다.
  • 이 함수는 식별번호(첫번째 인자)인 쓰레드를 detach시키는데, detach 되었을 경우, 해당(detach)된 쓰레드가 종료될 경우 pthread_join을 호출하지 않더라도 즉시 모든 자원이 해제(free) 된다.
  • detach를 하지 않을 경우, 쓰레드 함수가 종료되더라도 자원이 해제되지 않는다.
  • pthread_create 호출 후 detach할 수 도 있고, pthread_create 호출시에 쓰레드가 detach 되도록 할 수도 있다.(pthread_attr_setdetachstate 참조)
  • ex) pthread_detach(p_thread);

(4) pthread_exit
  • 현재 실행 중인 쓰레드를 종료시키고자 할 때 사용한다.
  • pthread_cleanup_push가 정의되어 있다면, pthread_exit가 호출될 경우 cleanup handler가 호출된다. 보통 이 cleanup handler는 메모리를 정리하는 등의 일을 하게 된다.
  • ex) pthread_exit(0);

(5) pthread_cleanup_push
  • cleanup handler를 인스톨하기 위해서 사용된다.
  • pthread_exit가 호출되어서 쓰레드가 종료될 때 pthread_cleanup_push에 의해서 인스톨된 함수가 호출된다.
  • 첫번째 인자가 쓰레드가 종료될 때 호출되는 함수이다.
  • 두번째 인자는 이 때의 아규먼트이다.
  • cleanup handler는 주로 자원을 돌려주거나, mutex 잠금등의 해제를 위한 용도로 사용된다. 만약 mutex 영역에서 pthread_exit가 호출되어 버릴 경우, 다른 쓰레드에서 영원히 block 될 수 있기 때문이다.
  • 또, malloc 으로 할당받은 메모리, 열린 파일지정자를 닫기 위해서도 사용한다.
  • ex) phread_cleanup_push(cleanup, (void *)&a);

(6) pthread_cleanup_pop
  • pthread_cleanup_push와 함께 사용되며, cleanup handler를 제거하기 위해서 사용된다.
  • pthread_cleanup_push와 pthread_cleanup_pop은 반드시 같은 함수 내의 같은 레벨의 블럭에서 한 쌍으로 사용해야 한다.

(7) pthread_self
  • pthread_self를 호출하는 현재 쓰레드의 쓰레드 식별자를 리턴한다.
  • ex) ptread_t id;        id = pthread_self();

2. 쓰레드 동기화 함수

(1) pthread_mutex_init
(2) pthread_mutex_distroy
(3) pthread_mutex_lock
(4) pthread_mutex_unlock
(5) pthread_cond_init
(6) pthread_cond_signal
(7) pthread_cond_boradcast
(8) pthread_cond_wait
(9) pthread_cond_timewait
(10) pthread_cond_destroy
(11) 예제 코드

3. Thread Attribute 함수

(1) pthread_attr_init
(2) pthread_attr_distroy
(3) pthread_attr_getscope
(4) pthread_attr_setscope

4. 쓰레드 시그널 관련

(1) pthread_sigmask
(2) pthread_kill
(3) sigwait

5. 쓰레드 취소
(1) pthread_cancel
(2) pthread_setcancelstate
(3) pthread_getcancelstate



getch(), getchar(), getche() 가 필요한 이유

< getch(), getchar(), getche() 가 필요한 이유 >

* 공통 기능
  • 키보드로부터 문자 하나를 입력 받아 리턴한다.
  • 키보드에서 문자가 눌러질 때까지 무한대로 대기한다.
  • 키보드 입력시까지 대기시키는 목적으로 많이 사용된다.
* getch()
  • 에코 기능이 없다.
  • 입력받은 문자를 리턴한다.
  • 확장키 코드가 입력되었을 때는 0을 리턴한다. 이 경우 getch를 한번 더 호출하면 확장키 코드를 얻을 수 있다.
* getchar()
  • getch() 함수와 비슷하다. 유닉스에서 사용가능
* getche()
  • getch() 함수와 같되 에코 기능이 있다.

### int fflush(FILE * stream);
  • 스트림에 할당되어 있는 버퍼를 비운다.
  • 버퍼를 비운다는 의미는 입력, 출력에 따라 의미가 다르다.
    • 출력시 : 출력 대기중에 임시적으로 버퍼에 있던 데이터들이 파일에 기록된다.
    • 입력시 : 버퍼에 있던 데이터를 모두 지운다. 그리고 다시 새로운 데이터를 입력 받게 된다.
  • 버퍼를 비운다는 말은 버퍼에 들어있는 데이터를 없앤다는 의미이다.
  • fflush 실행 후에도 스트림은 여전히 개방된 상태로 남는다.
  • 성공시 0을 리턴, 에러 발생시 EOF 리턴

### linux에는 getch() 함수가 없기 때문에 함수를 만들어 사용해야 한다.

#include <termios.h>
#include <unistd.h>

int mygetch(void)
{
    struct termios oldt, newt;
    int ch;

    tcgetattr( STDIN_FILENO, &oldt );

    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );

    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );

    return ch;
}





2010년 4월 2일 금요일

NFS 설정

< Mini2440 NFS 설정 >

1. NSF setting
#get /etc/exports
/opt/FriendlyARM/MINI2440/root_qtopia *(rw,sync,no_root_squash)


2. firewall disable
# lokkit => disabled


3. start and stop nfs server
# /etc/init.d/nfs start
#mount -t nfs localhost:/opt/FriendlyARM/MINI2440/root_qtopia /mnt/
# /etc/init.d/nfs stop


3.1 in nfs server in gui
# serviceconf
 nfs => enable


4. booting system via nfs
 1) Nand flash로 모드 전환
 2) 전원 케이블, 시리얼 케이블 네트워크 케이블 연결
 3) 터미널 오픈
 4) 타겟 보드 power on
 5) vivi shell에서
   Supervivi> param set linux_cmd_line "console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.70:192.168.1.111:192.168.1.111:255.255.255.0:MINI2440.arm9.net:eth0:off"

 6) vivi shell에서 boot 타이핑

2010년 3월 31일 수요일

r_write(재시작 함수)

< r_write(재시작 함수) >

시그널후의 read 함수와 write 함수의 재시작 문제와 요청한 모든 데이터를 쓰는 문제는 read 함수와 write 함수를 사용하는 거의 모든 프로그램에서 발생한다.

하여 r_read r_write 를 쓴다.

우선 read/write 함수의 에러의미를 확인해보자.

공통
EAGAIN
파일 디스크립터에 O_NONBLOCK 이 설정되어 있고, 쓰레드가 지연되었을 수 있다.

EINTR
read/write 는 시그널에 의해종료되고 데이터는 전송되지 않는다.

EINVAL
fd is attached to an object which is unsuitable for reading.
파일디스크립터가 read/write 에 적합한 개체가 아니다.

CD Player 개념 설명

< CD Player 개념 설명 >

  • 우리가 듣는 CD Player는 44.1khz에 16bit sample을 사용한다.
  • 그 말은 1초에 해당하는 음악을 44100개의 작은 조각으로 나누고, 각 조각의 음 높이를 16bit(0 ~ 65535)로 표현한다는 것이다.
  • 1초짜리 4096 bytes의 PCM 데이터를 11025hz로 재생하려면 interplation을 통해 데이터를 확장해야 한다.
  • 만약, 갖고 있는 sample이 4096hz, 8bit sample이라고 한다면,
    • 1초에 해당하는 음을 4096개의 조각으로 나누고, 각각의 음의 높이를 0 ~ 255의 값으로 표현한다는 얘기다.
    • 4096개의 조각을 1초 동안에 DA 컨버팅을 해야 1초에 해당하는 음이 들리게 되는 것이고, 만약, 11025hz로 재생하면 11025 / 4096 = 0.37 초 만에 재생되어 버리게 된다.
    • 한 개의 PCM sample만 재생을 한다면 대충 사용하면 된다. 하지만 여러 개의 PCM sample을 동시에 재생하는데 각 sample의 sampling rate가 다르다면 DSP의 sample rate를 고정시켜 놓은 상태에서 각 PCM sample을 interpolation을 통해 DSP의 sample rate로 변환하여 재생해야 한다.

2010년 3월 30일 화요일

사운드 카드에 대해서

< 사운드 카드에 대해서 >

  • 소리는 아날로그이다. 임의의 소리는 정해진 연속적인 범위내의 임의의 값에 해당한다.
  • 컴퓨터는 디지털이다. 컴퓨터는 불연속적인 값을 다루기를 좋아한다.
  • 사운드 카드는 Analog to Digital Conberter(ADC) 라고 하는 장치를 사용한다. 이것의 역할은 아날로그 소리(정확하게는 그것에 해당하는 전압)를 메모리에 저장할 수 있는 디지털 또는 수치값으로 변환시키는 것이다. 비슷하게 Digital to Analog Converter(DAC)는 수치값을 아날로그 전압으로 바꾸어 주며 이를 스피커를 통하여 들을 수 있는 것이다.
  • 샘플링(sampling)이라고 알려져 있는 아날로그를 디지털로 변환시키는 과정에서 약간의 손실이 발생한다. 샘플링된 신호가 원음에 얼마나 가까운가를 결정짓는 두 가지 요소가 있다.
    • 샘플링 속도(Sampling Rate)
      • 단위 시간당 얻어진 샘플의 갯수, Hertz로 표시
      • 샘플링 속도가 낮으면 원음을 정확하게 나타내기 어렵다.
    • 샘플 크기(Sample Size)
      • 샘플을 표현하기 위해 사용되는 값의 범위, bits로 표시
      • 샘플 크기가 크면 클수록 디지털 신호는 더 정확해질 것이다.
  • 사운드 카드는 대개 8 또는 16비트의 샘플 크기와 4000 ~ 44000 Herz 사이의 샘플링 속도를 사용한다.
  • 샘플은 하나의 채널(mono) 또는 두 개의 채널(stereo)을 포함할 수 있다.
  • MIDI(Musical Instrument Digital Interface) : 전자악기를 외부에서 제어하기 위한 하드웨어 및 소프트웨어의 표준 프로토콜
    • 전자 오르간의 건반을 누르는 등과 같은 어떤 사건은 MIDI 버스(bus)를 통하여 전달되며 MIDI 파일로 저장하여 다시 편집하거나 재생할 수 있다.
    • 많은 사운드 카드가 MIDI 인터페이스를 제공하며, 그렇지 않은 카드라 하더라도 카드 자체의 기능을 이용하여 MIDI 파일을 연주할 수 있다.

2010년 3월 29일 월요일

디지털 피아노의 원리

< 디지털 피아노의 원리 >
  • 스튜디오 안에서 콘서트형 그랜드피아노 소리를 터치 강약에 따른 5단계로 각각 달리 채취해 44.1khz로 샘플링한 사운드 데이터를 롬(ROM)에 저장하였다가 건반을 칠 경우 불러내 DAC(DA 컨버터)를 거쳐 아날로그 신호로 전환, 앰프와 스피커를 통해 재생하는 방식.
  • 즉, 연주자가 건반을 누르면 그 건반의 음이름이 무엇이고(몇 번째 키), 얼마나 세게 눌렀는지를 건반 밑에 있는 프로그램인 "러버 소프트웨어"가 동작시간으로 구분하고 이어 이러한 정보를 검색 IC가 CPU에 전달하게 된다.
  • 그렇게 되면 이 CPU가 컨트롤 측에 선택된 음색(피아노, 오르간 등)과 함께 동작 시간을 인지해 음발생기(톤 제너레이터)에 해당음을 만들도록 명령하면서 사운드 롬에 저장된 데이터를 불러내 디지털 신호로 만들고 DAC(DA 컨버터)를 거쳐 증폭기로 증폭하면 비로소 음을 들을 수 있게 된다.
  • 디지털 피아노는 일반 피아노의 원음과 터치를 얼마나 근접하게 표현할 수 있느냐가 관건이다.
  • PCM(Pulse Code Modulation)이란 방식에 힘입어 일반 CD의 44.1khz로 사운드 샘플링을 시작하게 된 80년대 후반부터 디지털 피아노 수요가 폭발적으로 증가했다.

mpeg technical 문서, audio programming on linux

본문스크랩 오디오 압축 기술 MP3 에 대하여 Mini Project
2007/02/27 17:10
출처 블로그 > SoundHolicA
원본 http://blog.naver.com/min1seok/120034958111
MP3의 정의
MP3란 우리가 컴퓨터에서 사용하는 .HWP,WAV, TXT 처럼 파일 확장자의 일부분이다.
MP3 란 ?MPEG(Motion Picture Experts Group : 동영상 전문가 그룹) Audio Layer-3의 줄임말로 MPEG 중에서 음성데이터를 압축하는 종류이다
정확히 말하면 'MPEG Audio Layer-3'의 줄인말이 MP3이다.

MPEG는 (Motion Pictures Expert Group.) 즉 동영상, 멀티미디어 전문가 그룹으로 이 분야에 관한 전문가들이 ISO(국제 표준화 기구)와 IEC (국제 전기 표준회의)와 같은 국제 표준 기구의 산하에 모여 제정한 규격으로 비디오와 오디오 신호를 압축해 전송하고 이를 다시 복원하는 것과 같은 기술적 기준을 제정하였다.
MPEG이 처음 만든 규격은 MPEG-1이고, 이는 비디오 CD를 제작할 때 사용하는 기술이고, MP3는 MPEG-1의 규격중 오디오 압축 부분을 의미한다.
MPEG-1과 함께 현재 사용되는 건 MPEG-2인데 최근 기술적으로 우수한 디지털 오디오로 관심을 받고 있는 AAC(Advanced Audio Coding or MP4)는 MPEG-2에서 파생되었고, MPEG-4(최신의 화상 통신용 동영상 압축 표준)에 관한 규격이 제정중에 있다고 한다.
MP3를 'MPEG Audio Layer-3'라고 했는데 이 Layer-3이라는 건 Layer-1, Layer-2 다음에 Layer-3으로 버전업이 된 것이다.
일반적으로 Layer-1은 압축율이 1:4 정도, Layer-2는 1:6 ~ 1:8 정도의 압축율을 갖고, Layer-3은 1:10 ~ 1:12의 가장 뛰어난 압축율을 갖기 때문에 MP3로 불리우고, 가장 많이 사용되는 것이다.
MP3 기술을 이용하면 650MB 기준으로 공CD 한장에 최소한 150여곡(대략 8시간) 이상의 노래를 담을 수 있다.
최근에는 이런 MP3 데이터로 만들어진 CD를 재생해주는 MP3-CD 플레이어(MP3CDP)가 출시돼 MP3 매니아에게 관심을 받고 있다.

탄생배경
MP3는 MPEG Audio Layer-3의 줄임말로 오디오 신호를 효과적으로 사용하기 위하여 고안된 압축 방식을 지칭하는 말이다.
멀티미디어 시대가 도래하여 동영상 및 음향의 디지탈 데이타가 증가하면서 데이타 크기의 폭증이라는 어려운 문제점이 나타나기 시작했는데, CD 한 장을 그대로 디지탈로 저장하기 위해서는 650M byte라는 상당히 많은 저장 용량이 필요하다.
멀티미디어 개발자들은 이런 문제점들을 해결하기 위해서 데이타를 압축하여 저장하는 방법을 사용할 수 밖에 없다는 것을 알았지만, 압축을 하게 되면 화질이나 음질에 큰 손실을 가져오기 때문에 이를 최소화하기 위한 연구들이 활발하게 진행되었다.
이런 연구를 뒷받침하기 위해서 세계적으로 압축 코딩의 표준이 마련되었는데 그것이 바로 MPEG(Moving Pictures Experts Group) 이다
. 잘 알려진 대로 비디오 CD의 동영상 포맷이 MPEG-1 규격으로 제작되어 있고, 최근 출시된 DVD 역시 보다 진보된 MPEG-2 방식의 압축 기술을 사용하고 있다.
MPEG은 이렇게 세계적인 영상 매체들의 표준을 이루는 중요한 규격으로 위성방송, 케이블방송 등을 위한 새로운 규격을 계속해서 만들고 있다.
이런 MPEG 규격 중에서도 오디오 데이타를 위한 규격들이 있는데 그 중 하나가 Audio Layer-3이라는 규격이다.
이 압축 방식을 사용하면 CD급의 음질을 유지하면서 데이타의 크기를 10분의 1 이상으로 축소할 수 있다.
그러나 이런 MP3 파일을 제작하거나 감상하기 위해서는 특수하게 제작된 인코더/디코더가 필요한데 이런 프로그램들은 대부분 프리웨어나 쉐어웨어 형태로 배포되기 때문에 인터넷 상에서 쉽게 구할 수 있다.
하지만 오디오 데이타를 압축하기 위한 표준은 아직 완벽하게 제정된 상태가 아니다.
DVD에서는 AC-3라는 입체음 방식이 채용되었지만 가정용 오디오 시장에는 아직도 MD(Mini Disk) 방식이 일본을 중심으로 상당히 강세를 나타내고 있으며, 인터넷 쪽에서는 RA(Real Audio) 포맷이 보급되어 있는 실정이어서 PC에 어떤 방식이 표준으로 채택될 지는 더 두고봐야 알 수 있을 것이다.
참고로 MD 레코더는 개발된지 꽤 오래되었기 때문에 비교적 압축률이 낮으며 MPEG Layer-1의 수준이라고 할 수 있다.
MPEG-1 이나 MPEG-2 모두 음향과 관련한 규약에 Layer 라는 구분을 두어 규약을 보다 세분화하고 있다.
좀 더 구체적으로 이야기하자면 MPEG-1, MPEG-2 Layer 1 에서는 Linear quantizer 가 특징적이며 MPEG-1, MPEG-2 Layer 2 에서는 Non-linear quantizer 와 longer frame 이, 마지막으로 MPEG-1, MPEG-2 Layer 3 (MP3) 에서는 Non-linear quantizer, longer frame, variable length 가 특징적이다.
높은 Layer 로 갈수록 데이터의 인코딩과 디코딩 기술이 좀 더 복잡해지며 더 다양한 기술(VBR 등)이 구현 가능하다. 또한 높은 Layer 용의 디코더는 하위 호환성을 갖는다.
참고로 MPEG-1 Audio Layer 2 는 MP2 라는 파일로 역시 한 시대를 풍미했었다.

디지털 오디오
MP3를 이해하려면 먼저 디지탈 오디오에 대한 기본적인 사항을 알아야 한다.
MP3 역시 디지탈 오디오의 한 포맷에 해당하기 때문이다.
우리가 가장 많이 접할 수 있는 디지탈 오디오로는 오디오 CD(Compact Disk)와 PC의 윈도우 시스템에서 사용하고 있는 Wave라는 파일 포맷이 있다.
즉, 디지탈 오디오는 자연상의 아날로그 방식의 사운드를 디지탈 방식으로 변환하여 저장하는 방식이다.
0과 1의 디지탈 데이타로 변환하게 되면 음질이 손상되지 않고 저장하는 것이 가능하고 또한 PC에서 마음대로 사용할 수 있다는 장점이 있다.
우리가 게임을 하면서 실감나는 현장 효과음을 즐길 수 있게 된 것도 모두 이 디지탈 사운드 덕분이다.
소리를 마치 텍스트 파일처럼 저장하고 필요할 때 마음대로 편집하고 재생할 수 있는 이 디지탈 사운드의 기술은 대중음악가들에게도 자신의 창의력을 구체화할 수 있는 중요한 도구로 활용되고 있다.
물론 디지탈 사운드를 감상하려면 인간이 청취할 수 있는 아날로그 사운드로 변환하는 작업을 다시 수행하여야 한다.
이런 과정을 DA(Digital to Analog) 컨버팅과 AD(Analog to Digital) 컨버팅이라 한다.
즉, 아날로그 원음을 디지탈로 변환하는 과정을 AD 컨버팅이라 하고, 디지탈로 저장된 데이타를 아날로그로 변환하여 감상할 수 있도록 하는 과정을 DA 컨버팅이라 한다.
우리가 사용하는 사운드 카드나 CD 플레이어는 모두 이런 기능을 수행하는 전자회로가 내장되어 있다.
디지탈 사운드에는 16bit의 44.1KHz와 같이 표현하는 변환 방식이라는 것이 있다.
이 형식은 아날로그 사운드를 디지탈로 변환할 때 얼마나 세밀한 요소로 분해하여 저장했는지를 나타내는 것이다.
즉, 8bit는 2의 8승인 256개로, 16bit는 2의 16승인 65356개로 분해하여 데이타를 저장했다는 이야기이고, 이렇게 분해하는 과정을 1초에 몇 번 반복했느냐는 의미로 KHz라는 단위를 사용한다.
44.1KHz라는 의미는 1초에 44100번 분해 작업을 수행했다는 의미이다.
분해도를 더욱 높이고 초당 분해 작업을 더 많이 할수록 원음에 가까운 사운드를 디지탈로 저장할 수 있다.
하지만 분해도를 높이면 엄청난 데이타의 크기 때문에 실용성이 떨어지므로, 실험 결과 인간의 귀로 원음과의 차이를 느낄 수 없다는 16bit에 44.1KHz 형식의 포맷을 많이 사용한다.
하지만 이 포맷도 1분당 약 10M byte의 대용량을 차지하기 때문에 통신을 이용해서 전송하기가 힘들다.
그래서 MP3 방식의 압축을 이용하여 CD급의 음질을 유지하면서 1분당 1M byte로 압축하는 방법을 사용한 것이 주목받게 되었다.
앞서 말 한 대로 MPEG-2 에도 Audio Layer 표준들이 존재한다. 이들은 MPEG-2 BC(Backward Compatible)의 범주에 속하는 것으로 아직까지 대중적으로 널리 퍼지지 않았기 때문에 딱히 MP3 와 같은 약칭은 가지고 있지 않다.
다만 MPEG-2 의 오디오와 관련한 또 하나의 규약인 MPEG-2 AAC(Advanced Audio Coding)는 일명 MP4 라고도 불리는 데, 엄밀히 말해 이것은 MP3에서 MP4 로 이어지는 흥행을 노리고자 일부에서 억지로 가져다 붙인 이름이기 때문에 정식 명칭이라고는 할 수 없다.
MPEG-2 AAC 는 MPEG-1 의 오디오 규약에 기반을 둔 MPEG-2 BC 와 비교했을 때 절반의 비트레이트 수준으로 보다 나은 음질을 들려 줄만큼 높은 스펙을 가진 규약이다.
멀티 채널 출력을 지원하는 MPEG-2 AAC 는 돌비(Dolby)의 비슷한 규약인 AC-3 에게 MPEG-2 BC 규약이 HDTV 오디오 표준화 전쟁에서 밀리게 되자 굴지의 업체들이 참여해 급히 제정한 것이라는 배경을 가지고 있다.

압축원리
MP3의 압축 방식은 우리가 알고 있는 Zip이나 Arj 등과 같은 일반적인 압축 방법과는 매우 다른 복잡한 알고리즘을 갖고 있다.
이런 압축 방법들은 주로 비파괴적인 압축 방식을 사용한다.
비파괴적인 압축 방식이란 데이타를 압축 복원하는 과정에서 데이타가 변경되거나 손실되는 것이 전혀 없는 방식이다.
예를 들어 '한글'로 작업한 문서를 Zip으로 압축해서 인터넷으로 송신했다고 하자.
만약 Zip을 압축하거나 복원하는 과정에서 데이타가 변경되거나 손실이 생긴다면 문서를 받는 사람이 그 내용을 정확하게 알아볼 수 없다.
이런 비파괴적인 압축의 알고리즘은 상당히 단순하다.
주로 연속되는 같은 데이타를 하나와 반복 횟수로 표시하는 방법을 사용한다.
'12222223334'라는 데이타가 있다고 할 때, 이 데이타를 압축하면 '12-63-34'라는 식으로 압축할 수 있다.
원래의 데이타가 11자인데 비해 압축한 후에는 8자로 줄어든다.
압축한 데이타의 표현식을 보면 '2-6'이라는 것은 2가 6번 반복되었다는 것을 의미한다.
'3-3'도 역시 3이 3번 반복되었다는 것을 의미한다. 따라서 같은 데이타의 반복이 많은 파일일수록 압축률은 높아진다.
그러면 '한글' 파일과 윈도우용 사운드 파일인 Wave 파일을 WinZip이라는 압축 프로그램을 사용해 압축해 보자.
결과는 '한글'의 경우(물론 정도차는 있겠지만) 3분의 1 이상 줄어든 반면 디지탈 사운드인 Wave 파일은 약간밖에는 줄어들지 않는다.
이유는 사운드와 같은 멀티미디어 데이타들은 일반 문서나 실행 파일과는 달리 연속되는 데이타가 적기 때문에 압축률이 떨어지기 때문이다.
따라서 사운드 파일은 일반적인 비파괴적인 방법으로 압축하지 않고 다른 복잡한 알고리즘을 가진 파괴적인 압축 방법을 사용하게 되는 것이다.
파괴적인 압축 방식이란 불필요한 데이타를 삭제하는 방식으로 압축을 하는 것이고 한번 압축한 후에는 원형으로 복원이 어려운 반면 압축률은 상당히 높아진다.
따라서 일반 문서나 실행 파일과 같이 정확한 복원을 목적으로 하는 경우에는 사용할 수 없는 반면 사운드나 그림 데이타와 같이 약간의 음질 손상이나 화질 저하에도 무리가 없는 경우에 사용한다.
JPEG이나 MPEG 등이 파괴적인 압축 방식에 속한다.
그렇다면 이제 MP3의 경우에는 어떤 방식으로 압축이 수행되는지를 알아보자.
여러분이 지하철 플랫폼에서 친구와 이야기를 하고 있는 상황을 생각해 보자.
전동차가 도착하기 전에는 친구와 작은 목소리로 대화를 나눌 수 있는데 전동차가 들어오기 시작하면 그 소음으로 인하여 친구의 목소리는 잘 들리지 않게 된다.
또한 전동차가 지나가도 잠시 동안은 그 소리의 여운으로 귀가 멍해진다.
음악에서도 이와 마찬가지로 큰 소리가 난 후에는 작은 소리는 인간의 귀로 들을 수 없는 경우가 있다.
이런 현상은 인간의 두뇌가 소리를 분석해 내는 과정에서 입력된 소리의 부적절한 부분을 제거하는 작용을 하기 때문이다.
MP3는 디지탈 사운드를 미리 분석해서 인간의 두뇌가 걸러낼 사운드를 미리 잘라내는 방식으로 압축을 수행한다. 그렇기 때문에 CD급의 음질을 유지하면서도 상당한 수준의 압축률을 올릴 수 있는 것이다.
사실 오디오 전문가가 아닌 일반인들의 능력으로는 압축 전의 디지탈 사운드와 MP3를 구별해내기 힘든 이유가 여기에 있는 것이다.
이런 압축 방식을 '인지 압축 방식(Perceptual Coding)'이라고 한다.
아날로그 음원을 MP3로 압축하는 과정을 간략히 나타내면 다음과 같다.
아날로그 음원 -> AD 컨버팅 -> 디지탈 PCM 파형 -> 20Hz에서 20KHz 사이의 주파수를 32단계로 분해 -> 분해된 한 단계를 다시 18단계로 세분 (총 576부분) -> 각 세부된 부분에서 가장 강한 음의 성분에 대한 정보만을 선택 -> 나머지 음에 대한 음의 정보 삭제 -> 세분된 576부분의 강음 정보만을 모아 재합성 -> MP3 파일

MPEG 종류
MPEG은 MPEG-1, MPEG-2가 현재 사용중이고 MPEG-4에 관한 규격이 재정중인데 오디오의 경우에는 주로 MPEG-1을 사용하기 때문에 일반적으로 MPEG 규격이라고 통칭된다.
MPEG 규격의 오디오 부분은 Layer-1, Layer-2 및 Layer-3라는 세부 규격으로 나누어진다.
Layer-1 : 압축률 1:4, 스테레오 신호의 경우 384Kbps에 해당 Layer-2 : 압축률 1:6~1:8, 스테레오 신호의 경우 256~192Kbps에 해당 Layer-3 : 암축률 1:10~1:12, 스테레오 신호의 경우 128~112Kbps에 해당
Layer-1은 필립스사에서 DDC(Digital Compact Cassette)를 위해 개발된 PASC 압축 알고리즘을 위해 사용되었으며, Layer-2 및 Layer-3으로 갈수록 보다 발전되어 더 큰 압축으로도 우수한 음질을 낼 수 있게 되었다.
현재 인기를 얻고 있는 MPEG-1 Audio Layer-3은 독일의 프라운호퍼 연구소에서 디지탈 오디오 방송을 위해 개발한 방식이다.
음을 주파수 대역별로 나누어 이를 압축하는 방법을 사용하는데 인간의 청각에 의한 음의 인지 패턴을 교묘히 이용하는 방식으로 압축한다.
음의 세기가 큰 음과 작은 음이 동시에 들릴 때는 작은 음은 큰 음의 소리에 묻혀서 잘 들리지 않게 된다.
이러한 청각적인 인식 효과를 마스킹 효과(Masking Effect)라고 하는데, MPEG-1 Audio Layer-3 방식에서는 우선 가청 주파수를 32부분으로 나누고 각 부분을 다시 18부분으로 세분해 총 576개의 세부 부분으로 나눈 다음 각 부분마다 마스킹 효과를 적용시켜 각 576부분마다 음이 주도적으로 큰 성분만을 남기고 나머지 부분은 제거한 다음 각 부분을 다시 합성하는 방법으로 압축 작업을 진행한다.
기본적으로 DDC및 MD(Mini DIsk)에서 사용하는 압축 방법과 개념은 비슷하나 이를 더욱 많이 개량한 것이라 할 수 있다. 이 방식은 다음과 같이 여러 가지 모드가 있어 원하는 형태로 압축해 사용할 수 있다.
오디오 파일을 압축해 인터넷과 같은 통신 라인을 통해 전송하고자 하는 것이 MPEG 규격 개발 목적의 하나이다.
IDSN 전화선을 통해서는 128Kbps의 속도를 얻을 수 있으므로 CD 수준 음질의 음악을 실시간으로 전송받을 수 있으며, 56Kbps급의 모뎀을 사용하는 경우에는 FM 라디오 수준의 음질로, 33.6Kbps급의 모뎀을 사용하는 경우에는 AM 라디오 수준의 음질로 실시간에 전송받을 수 있다.
일반적으로 많이 사용하는 모드는 CD 수준의 음을 들려주는 112~128Kbps급의 모드이다.
MPEG-1 Audio Layer-3 규격을 마이크로소프트사에서는 Wave 파일의 Layer-3 압축 포맷으로 새로이 지원하고 있다.
이는 마이크로소프트사에서 제작한 NetShow 2.0이라는 인터넷 오디오/비디오 스트리밍 소프트웨어에서 이 포맷을 포함시켰기 때문이다.
이 포맷과 MP3 확장자를 가지는 포맷은 동일하기 때문에 확장자 이름이 다를지라도 상호 호환된다.
한편 최근 들어 MP4라는 규격도 소개되었는데 MP4는 MP3와 성격이 비슷하면서도 뿌리가 다르다.
MP4의 공식 명칭은 MPEG-2 AAC(Advanced Audio Coding)로 MPEG-2 NBC(Non Backwards Compatibility)라고도 부른다.
공식적인 이름은 아니지만, 친근감이 있고 MP3의 상위 버전처럼 느껴지도록 MP4라는 이름으로도 불려지고 있다.
MPEG-2 AAC는 MP3처럼 압축된 오디오 데이타이지만 탄생 배경이 다르다.
이름에서 알 수 있듯이 MPEG-1이 아닌 MPEG-2에서 파생되었다.
DVD 비디오용으로도 사용되는 MPEG-2는 MPEG-1에 비해 4배의 화질과 다중 언어 지원 등으로 성능이 우수하다.
AT&T, 톰슨, 프라우호퍼 등의 업체가 공동으로 만든 이 규격은 MP3에 비해 음질이 우수하고 압축률이 높다.
MP3의 데이타 구조가 고정적인 반면 AAC의 데이타는 유동적인 구조를 갖는다.
MP3는 곡 전체의 정보를 담는 헤더 뒤에 데이타가 프레임이라는 단위로 저장되는데 이 프레임의 크기가 고정되어 있어 압축률이 높은 부분에서도 쓸모없는 용량을 차지한다.
이에 반해 AAC의 프레임 구조는 가변 구조로 압축률에 따라 크기가 변하므로 전체 파일의 용량이 훨씬 줄어든다.
실제로 MP3 파일과 비교하면 최대 30%까지 용량을 줄일 수 있다.
AAC의 또 하나의 장점은 음질에 있다.
MP3에 비해 AAC는 TNS와 프레딕션이라는 두 가지 기법을 통해 음질을 향상한다.
TNS(Temporal Noise Shaping)는 양자화 보정 기술로 아날로그의 연속적인 음악 데이타를 0과 1의 디지탈 데이타로 만들 때 생기는 오차를 지능적으로 줄여 잡음을 감소시키고 원음에 가깝게 만든다.
프레딕션(Prediction)이란 TNS로 보정된 수치를 기억하는 것으로 앞에서 보정된 정보를 기억하여 다음에 같은 데이타가 나타날 때 기억된 데이타를 사용한다.
만일 양자화 단계에서 같은 음의 보정 수치가 다르면 다른 소리로 들리게 되므로 이를 같게 만드는 기술이다.
이같이 MPEG-2 AAC는 압축률과 음질 면에서 MP3 보다 우위에 있지만 AAC는 아직 해결해야 할 문제가 적지 않다. 그 중 한 가지가 인코딩 시간이다.
원음을 AAC 포맷으로 만드는 인코딩 시간이 MP3에 비해 최대 10배 이상 느리다.
물론 인코딩 소프트웨어의 성능 향상으로 이 문제는 차츰 개선되겠지만 인코딩 시간이 느려 AAC의 데이타를 만드는데 많은 시간이 소요된다는 것으 치명적인 약점이다

발전방향
MP3는 MPEG의 발전과 함께 시작되었다.
1987년 독일의 IIS(Institut fur Integrierte Schaltungen)라는 곳에서 유레카 UE147이라는 프로젝트로 심리음성학에 의거한 인지 압축 기술이 연구되기 시작하였고 결국 매우 강력한 기능의 표준화된 ISO MPEG Layer-3을 개발했다.
프라운호퍼 IIS에서는 이런 MP3의 보급을 위해 Winplay3라는 재생프로그램을 보급하여 MP3의 보급에 획기적인 전기를 마련하였다.
또한 독일의 라디오 채널인 FFN은 전화선을 이용한 ISDN 장비를 이용해 매일 20분씩 8개의 프로그램을 중앙 방송 스튜디오에 송출했는데 이로 인해 1년에 30만 달러의 운반비를 절약할 수 있었다고 한다.
한편 프랑스 알베르빌에서 열린 동계 올림픽에서 독일의 라디오 방송은 MP3를 이용한 깨끗한 음질로 스포츠 생중계를 실시하는 등 MP3가 디지탈 오디오 방송의 강력한 도구임을 증명하였다.
MP3를 이용한 전세계적인 위성 오디오 방송이 준비중에 있으며 간단한 라디오만으로 CD급의 고풉질 오디오를 세계 어디서나 감상할 수 있는 시대가 왔다.
또한 인터넷을 통한 주문형 오디오(Audio On Demand) 서비스가 활발하게 이루어지고 있으며, 워크맨으로 음악을 감상하듯이 거리를 걸으면서 MP3를 감상할 수 있는 휴대용 MP3 재생기도 인기리에 보급되고 있다.
[GTK+] 참고사이트 정리 Mini Project
2007/02/19 16:14

[Reference]
+ Embedded
- http://kelp.or.kr/
- http://qplus.or.kr/
[Tools]
+ Anjuta (IDE: Integrated Develop Environment) Version 1.2.2
+ GLADE(UI Designer) Version 2.10.0

[Libraries]
+ GTK+-2.0 Compatible Version 2.6.7
+ Atk, Pango, Glib, pthread, Etc...
+ GTK+ Dependency Library
+ MAD: MPEG audio decoding library
본문스크랩 MP3 플레이어 국내외 시장동향 Mini Project
2007/02/05 18:34
출처 블로그 > inside-India
원본 http://blog.naver.com/redarcas/60013190961
MP3 플레이어 국내외 시장동향
1. 개요
디지털화된 음향을 재생하는 기기로 CD(Compact Disk) 플레이어, DVD(Digital Versatile Disk) 오디오 플레이어, MD(Mini Disk) 플레이어, MP3 플레이어 등이 있는데, MP3 플레이어가 현재 가장 진보된 기술을 채택한 기기이며, 많은 인기를 끌고 있어 시장이 크게 성장하고 있다.
일반적으로 MP3 플레이어라 알려진 디지털 압축 오디오 플레이어는 압축된 디지털 오디오 파일들을 재생하는데 이용되는 기기로 휴대용, 가정용 차량용 등으로 구분되기도 한다. MP3(MPEG Audio Layer-3), WMA(Windows Media Audio) 등과 같은 압축 오디오 파일은 주로 인터넷에서 다운로드 받거나, 오디오 CD로부터 PC를 통하여 인코딩된다.
이처럼 인터넷 오디오 플레이어라 불리기도 하는 MP3 플레이어는 Diamond Multimedia 의 Rio PMP300으로 1998년 11월에 처음으로 소개되었고, 국내의 경우는 이보다 약 1년 정도 앞선 1997년 엠피맨닷컴(구 새한정보 시스템)이 MPman을 출시한 바 있다.
과거 수년간 디지털 오디오 압축 기술의 사용과 인터넷을 통한 디지털 음악의 공유는 놀랄 만큼 증가하였고, 이로 인해 많은 사람들은 MP3나 Napster 등에 친근해질 수 있었으며, 디지털 저작권 등과 같은 여러 가지 이슈를 야기시키기도 하였다. 또한 디지털 음악의 인기는 MP3 플레이어로 잘 알려진 휴대용 디지털 음향재생기 시장의 성장을 촉진하였다.
(그림1)은 MP3 플레이어의 내부와 재생과정을 보여주고 있다. 그림에서 보는 것처럼 MP3 플레이어의 내부는 LCD 패널, 마이크로 프로세서, DSP 칩, I/O 컨트롤러 칩, 버튼 등으로 구성되어 있고, 음원인 MP3 포맷 파일은 마이크로 프로세서의 명령을 통해 메모리로부터 DSP를 거쳐 앰프에서 증폭되어 스피커 또는 헤드폰으로 재생된다.


본문스크랩 linux Sound Programming Mini Project
2007/02/25 05:37
출처 블로그 > Digital GongDoRi
원본 http://blog.naver.com/jinkaien/140034390322
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)에서 다루고 있다 . 그러나 위의 부분 들을 잘 이해 하고 있다면 많은 오디오 관련 프로그래밍을 할때에 큰 힘이 될것이다.
MPEG Technical 문서 Mini Project
2007/03/01 06:30

Technical audio papers



출처: http://www.mp3-tech.org/