Microsoft PowerPoint - chap08-Ogg Vorbis Playback in OpenAL.pptx

Similar documents
chap7.key

슬라이드 1

K&R2 Reference Manual 번역본

BMP 파일 처리

11장 포인터

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

API 매뉴얼

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Chapter #01 Subject

13주-14주proc.PDF

untitled

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

chap 5: Trees

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C4C656D70656C2D5A69762E637070>

3주차_Core Audio_ key


<4D F736F F F696E74202D20C1A63137C0E520B5BFC0FBB8DEB8F0B8AEBFCD20BFACB0E1B8AEBDBAC6AE>

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

歯9장.PDF

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

슬라이드 1

Microsoft PowerPoint APUE(File InO).pptx

The Pocket Guide to TCP/IP Sockets: C Version

인켈(국문)pdf.pdf

Chapter 4. LISTS

03장.스택.key

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

Microsoft PowerPoint - ch07 - 포인터 pm0415

bn2019_2

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

2007_2_project4

T100MD+

Chapter 4. LISTS

슬라이드 1

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

UI TASK & KEY EVENT

1 1. INTRODUCTION 2 2. DOWNLOAD Windows Desktop & Server Max OS X, Linux, Windows CE 2 3. API REFERENCE CAN_OpenVcp CAN_Op

SRC PLUS 제어기 MANUAL

PowerPoint 프레젠테이션

Chapter 4. LISTS

UI TASK & KEY EVENT

금오공대 컴퓨터공학전공 강의자료

슬라이드 1

The Pocket Guide to TCP/IP Sockets: C Version

6주차.key

5.스택(강의자료).key

강의10

금오공대 컴퓨터공학전공 강의자료

Lab 3. 실습문제 (Single linked list)_해답.hwp

PowerPoint Presentation

10.

1217 WebTrafMon II

Microsoft PowerPoint - a10.ppt [호환 모드]

Microsoft PowerPoint - chap10-함수의활용.pptx

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

본 강의에 들어가기 전

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

<32B1B3BDC32E687770>

03_queue

KEY 디바이스 드라이버

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

untitled

Mango220 Android How to compile and Transfer image to Target

Microsoft PowerPoint - IP11.pptx

Microsoft PowerPoint - chap11-포인터의활용.pptx

The C++ Programming Language 5 장포인터, 배열, 구조체 5.9 연습문제 다음의선언문을순서대로작성해보자. 문자에대한포인터, 10개정수의배열, 10개정수의배열의참조자, 문자열의배열에대한포인터, 문자에대한포인터에대한포인터, 상수정수, 상수

untitled


PowerPoint 프레젠테이션

<4D F736F F F696E74202D20C1A63132B0AD20B5BFC0FB20B8DEB8F0B8AEC7D2B4E7>

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

C프로-3장c03逞풚

Chap06(Interprocess Communication).PDF

The Pocket Guide to TCP/IP Sockets: C Version

USB-AIO11 API

/chroot/lib/ /chroot/etc/

untitled

Microsoft PowerPoint - chap06-2pointer.ppt

Microsoft PowerPoint - chap4 [호환 모드]

MPLAB C18 C

금오공대 컴퓨터공학전공 강의자료

adfasdfasfdasfasfadf

hd1300_k_v1r2_Final_.PDF

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

hlogin2


9

. "" "",.... :...,,....,.. :..,,,..,,...,.... 2

10주차.key

스마트폰 모바일 랩 세미나

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

Microsoft PowerPoint - Chapter_09.pptx

Transcription:

Sound Programming 제 8 장 Ogg Vorbis Playback in OpenAL 1 Overview of Ogg Vorbis An open-source sound codec created by Xiphophorus www.xiph.org popular on Linux due to its open-source heritage an alternative to MP3 Wav vs. Ogg Vorbis Ogg Vorbis allows you to decode the format yourself without having to pay a fee. Ogg Vorbis vs. MP3 vs. WMA? Which one do you like better? 2

Ogg Vorbis 의구조 Ogg Vorbis API 는크게 4 개의라이브러리로구성 Ogg library Ogg 파일을다루기위한 general-purpose routine들을지원 Ogg 라이브러리는 Vorbis를알지못함. Ogg 라이브러리는실제다루는파일이사운드인지동영상인지, 이미지인지도구분하지않음 멀티미디어데이터처리를위한 base framework 를제공할뿐임. Vorbis library Vorbisenc 를이용하여 Vorbis 방식으로압축된사운드스트림을디코딩할때필요한함수들을제공한다. 3 Ogg Vorbis 의구조 Ogg Vorbis 의구조 ( 계속 ) Vorbisenc library Vorbis 파일로의인코딩을지원하는라이브러리 Vorbis 인코더함수일체를지원한다. CD를 Ogg Vorgis 파일로만든다거나, Wav 파일을 Ogg Vorbis 파일로만드는등의일을할때에는꼭필요한라이브러리임. Vorbisfile library Ogg Vorbis 파일을쉽게다룰수있게해주는편의라이브러리 Ogg와 Vorbis 라이브러리들을감싸고있으며, 사용하기편리한인터페이스를제공한다. 특히, Vorbis 파일을디코딩할때편리한기능을제공 4

Using the Vorbisfile API Ogg Vorbis API 를감싸매우사용하기편하게만들어놓은라이브러리 Ogg Vorbis 파일을읽고압축을해제하여, 이를 PCM 스트림으로변환하는과정을아주편리한몇개의함수만으로지원함. Vorbisfile API를사용하는 flowchart 이번장에서우리는 Ogg Vorbis API 중 Vorbisfile API 만을사용할것임! 5 Using the Vorbisfile API Setup/Teardown API ov_open_callbacks() 주어진 file handle로부터 Ogg Vorbis bitstream을초기화하고, custom file/bitstream manipulation 루틴들을초기화한다. int ov_open_callbacks( void *datasource, // 이미오픈된.ogg 파일의 FILE * 를넘기면됨 OggVorbis_File *vf, // 정보가채워질 OggVorbis_File 구조체를가리키는포인터 char *initial, // Typically set to NULL long ibytes, // Typically set to 0 ov_callbacks callbacks // A completed ov_callbacks struct which indicates desired // custom file manipulation routines ); 리턴값 0 for success less than zero for failure 6

Using the Vorbisfile API Setup/Teardown API ( 계속 ) ov_open_callbacks() ( 계속 ) ov_callbacks 구조체 typedef struct size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); int (*close_func) (void *datasource); long 0 (*tell_func) for success (void *datasource); ov_callbacks; less than zero for failure ov_clear() bitstream 과.ogg 파일을닫고, cleans up loose ends. Must be called when finished with the bitstream int ov_clear(oggvorbis_file *vf); 7 Using the Vorbisfile API ogg 파일정보얻기 ov_info() 주어진 ogg bitstream 의정보를담은 vorbis_info 구조체포인터를리턴한다. vorbis_info *ov_info( OggVorbis_File *vf, // OggVorbis_File 구조체를가리키는포인터 : // ov_open_callbacks() 으로부터넘겨받은것이어야함. int link // 대부분의경우 -1 ); 리턴값 : 정보가채워진 vorbis_info 구조체를가리키는포인터 vorbis_info 구조체 : vorbis/codec.h 파일에정의되어있음 파일버전, 채널수, sample rate, Bitrate(CBR 인경우 ) 등의정보를담고있음. 8

Using the Vorbisfile API ogg 파일정보얻기 ( 계속 ) ov_pcm_total() 주어진 ogg bitstream에있는총pcm 샘플링횟수를리턴한다. 디코딩했을때차지할바이트수계산에활용할수있음. ogg_int64_t ov_pcm_total( OggVorbis_File *vf, int link // 대부분의경우 -1 ); 9 Using the Vorbisfile API Decoding ov_read() long ov_read( OggVorbis_File *vf, // OggVorbis_File 구조체를가리키는포인터 char *buffer, // 압축해제된 PCM 데이터가저장될버퍼포인터 int length, // buffer로읽어들일바이트수. 버퍼의크기와같은크기 // 이어야함. 대개 4096이면적당. int bigendianp, // Specifies big or little endian byte packing. // 0 for little endian, 1 for big endian. 보통은 0. int word, // word 크기를지정한다. 1 for 8-bit samples, // or 2 for 16-bit samples. 보통은 2. int sgned, // Signed or unsigned data. // 0 for unsigned, 1 for signed. 보통은 1. int *bitstream); // A pointer to the number of the current logical bitstream. 응용프로그램에서 ogg 파일을디코딩할때사용되는주함수. 압축해제된 PCM 오디오데이터를지정된길이만큼리턴한다. endianness, signedness, 그리고 word 크기도고려함. 인코딩된오디오가 multichannel 이면, 각채널들이출력버퍼에인터리빙되어채워진다. 10

Using the Vorbisfile API Decoding ( 계속 ) ov_read()( 계속 ) Return Values OV_HOLE 파일안에빈곳이있어디코딩에실패함 ( 사유 : 파일페이지사이에쓰레기데이터가있음, recapture가바로따라오는바람에동기화정보가사라짐, 또는파일페이지자체가깨짐 ) OV_EBADLINK indicates that an invalid stream section was supplied to libvorbisfile, or the requested link is corrupt. 0 indicates EOF n indicates actual number of bytes read ov_read() 는일단호출되면 vorbis packet 단위로디코딩하기때문에, 이리턴값이인자에지정한 length 값보다작을수있음. 11.ogg 파일재생과정 단계 1:.ogg Wav 스트림변환과정 Ogg Vorbis 파일을 open하고 decoding 한다. 디코딩된 Ogg Vorbis 스트림은압축되어있지않은 PCM stream 이라고할수있다. 단계 2: 이 PCM stream을 OpenAL Buffer에담는다. 단계 3: OpenAL Buffer와 Source를연결하여재생 12

8 장예제 (PlayOggVorbis) main() #include "Framework.h" #include "Vorbis\vorbisfile.h" #include "alloadoggvorbis.h" #define SERVICE_UPDATE_PERIOD 250 #define TEST_OGGVORBIS_FILE " 아이유-06-삼촌 (Feat. 이적 ).ogg" int main() ALuint uibuffer; ALuint uisource; Alint istate; // Initialize Framework ALFWInit(); ALFWprintf("PlayOggVorbis Test Application\n"); // Initialize OggVorbis libary InitVorbisFile(); if (!g_bvorbisinit) ALFWprintf("Failed to find OggVorbis DLLs (vorbisfile.dll,ogg.dll,or vorbis.dll)\n"); ALFWShutdown(); // Initialise OpenAL if (!ALFWInitOpenAL()) ALFWprintf("Failed to initialize OpenAL\n"); ALFWShutdown(); 13 8 장예제 (PlayOggVorbis) main() ( 계속 ) // Open the OggVorbis file FILE *poggvorbisfile = fopen(alfwaddmediapath(test_oggvorbis_file), "rb"); if (!poggvorbisfile) ALFWprintf("Could not find %s\n", ALFWaddMediaPath(TEST_OGGVORBIS_FILE)); ShutdownVorbisFile(); ALFWShutdownOpenAL(); ALFWShutdown(); // ( 가장중요한부분 ) OggVorbis 스트림을디코딩하여 Wav PCM 스트림으로바꾸고 // OpenAL buffer 에이를채운후 buffer ID 를리턴한다. uibuffer = LoadOggVorbis(pOggVorbisFile); if (uibuffer < 0) ALFWprintf("Could not decode %s to PCM.\n", ALFWaddMediaPath(TEST_OGGVORBIS_FILE)); ShutdownVorbisFile(); ALFWShutdownOpenAL(); ALFWShutdown(); // Generate a Source to playback the Buffers algensources( 1, &uisource ); // 소스와버퍼를연결한다. alsourcei(uisource, AL_BUFFER, uibuffer); // Start playing source alsourceplay(uisource); 14

8 장예제 (PlayOggVorbis) main() ( 계속 ) // 종료검사 while (!ALFWKeyPress()) ALFWprintf("."); Sleep( SERVICE_UPDATE_PERIOD ); algetsourcei(uisource, AL_SOURCE_STATE, &istate); if (istate!= AL_PLAYING) // Finished playing break; ALFWGetKey(); ALFWprintf("\n"); // Stop the Source and clear the Queue alsourcestop(uisource); // Clean up buffers and sources aldeletesources(1, &uisource); aldeletebuffers(1, &uibuffer); // Shutdown VorbisFile Library ShutdownVorbisFile(); // Shutdown AL ALFWShutdownOpenAL(); // Shutdown Framework ALFWShutdown(); return 0; 15 8 장예제 (PlayOggVorbis) 의중요함수들 // Try and load Vorbis DLLs (VorbisFile.dll will load ogg.dll and vorbis.dll) void InitVorbisFile(void) if (g_bvorbisinit) return; g_hvorbisfiledll = LoadLibrary("vorbisfile.dll"); if (g_hvorbisfiledll) fn_ov_clear = (LPOVCLEAR)GetProcAddress(g_hVorbisFileDLL, "ov_clear"); fn_ov_read = (LPOVREAD)GetProcAddress(g_hVorbisFileDLL, "ov_read"); fn_ov_pcm_total = (LPOVPCMTOTAL)GetProcAddress(g_hVorbisFileDLL, "ov_pcm_total"); fn_ov_info = (LPOVINFO)GetProcAddress(g_hVorbisFileDLL, "ov_info"); fn_ov_comment = (LPOVCOMMENT)GetProcAddress(g_hVorbisFileDLL, "ov_comment"); fn_ov_open_callbacks = (LPOVOPENCALLBACKS)GetProcAddress(g_hVorbisFileDLL, "ov_open_callbacks"); if (fn_ov_clear && fn_ov_read && fn_ov_pcm_total && fn_ov_info && fn_ov_comment && fn_ov_open_callbacks) g_bvorbisinit = true; // 동적으로로드했던 vorbisfile.dll 을내린다. ogg.dll 과 vorbis.dll 도같이자동으로내려감. void ShutdownVorbisFile(void) if (g_hvorbisfiledll) FreeLibrary(g_hVorbisFileDLL); g_hvorbisfiledll = NULL; g_bvorbisinit = false; 16

8 장예제 (PlayOggVorbis) 의중요함수들 ogg 파일로딩 & 디코딩 & OpenAL Buffer 생성 // ogg 파일을읽고디코딩한후메모리에담는다. 그런후 OpenAL buffer를생성하고이 buffer에 // 디코딩한 Wav PCM 데이터를넣고이 buffer의 ID를리턴한다. ALint LoadOggVorbis(FILE *f) OggVorbis_File vf; // Ogg 파일객체정의 vorbis_info *vi; // ogg 파일정보객체 ov_callbacks scallbacks; ALuint uibuffer; unsigned long ulformat = 0; unsigned long ulbuffersize = 0; unsigned long ulfrequency = 0; unsigned long ulchannels = 0; unsigned long ultotalsamples = 0; unsigned long ulbyteswritten; char *pdecodebuffer; scallbacks.read_func = ov_read_func; scallbacks.seek_func = ov_seek_func; scallbacks.close_func = ov_close_func; scallbacks.tell_func = ov_tell_func; // Create an OggVorbis file stream if (fn_ov_open_callbacks(f, &vf, NULL, 0, scallbacks)!= 0) ALFWprintf("LoadOggVorbis: Input file does not appear to be an Ogg bitstream.\n"); fclose(f); vi = fn_ov_info(&vf, -1); // ogg 파일정보를얻는다. 17 8 장예제 (PlayOggVorbis) 의중요함수들 ogg 파일로딩 & 디코딩 & OpenAL Buffer 생성 ( 계속 ) ultotalsamples = (unsigned int)fn_ov_pcm_total(&vf, -1); // 샘플링전체개수 ulchannels = vi->channels; // 채널수 ulfrequency = vi->rate; // 초당샘플링횟수 ulbuffersize = ultotalsamples * ulchannels * 2; // 압축해제후의 PCM 데이터크기 // 주의 : The Buffer Size must be an exact multiple of the BlockAlignment... ulbuffersize -= (ulbuffersize % (ulchannels * 2)); if (ulchannels == 1) ulformat = AL_FORMAT_MONO16; else if (ulchannels == 2) ulformat = AL_FORMAT_STEREO16; else if (ulchannels == 4) ulformat = algetenumvalue("al_format_quad16"); else if (ulchannels == 6) ulformat = algetenumvalue("al_format_51chn16"); if (ulformat!= 0) // 압축해제후의음원포맷을알아낼수있는경우에만디코딩한다. // Allocate a buffer to be used to store decoded data for all Buffers pdecodebuffer = (char*)malloc(ulbuffersize); if (!pdecodebuffer) ALFWprintf("LoadOggVorbis: Failed to allocate memory for decoded OggVorbis data\n"); fn_ov_clear(&vf); // Generate some AL Buffers for streaming algenbuffers(1, &uibuffer); 18

8 장예제 (PlayOggVorbis) 의중요함수들 ogg 파일로딩 & 디코딩 & OpenAL Buffer 생성 ( 계속 ) // ogg 파일을디코딩하여 Wav 데이터를얻고, 이를 OpenAL 버퍼에넣는다. ulbyteswritten = DecodeOggVorbis(&vf, pdecodebuffer, ulbuffersize, ulchannels); if (ulbyteswritten) albufferdata(uibuffer, ulformat, pdecodebuffer, ulbyteswritten, ulfrequency); // Close OggVorbis stream fn_ov_clear(&vf); // 디코딩에사용했던메모리반환 if (pdecodebuffer) free(pdecodebuffer); pdecodebuffer = NULL; return uibuffer; else // 압축후음원의포맷을알아낼수없으면오류처리함 ALFWprintf("LoadOggVorbis: Failed to find format information, or unsupported format\n"); // Close OggVorbis stream fn_ov_clear(&vf); 19 8 장예제 (PlayOggVorbis) 의중요함수들 ogg 파일로딩 & 디코딩 & OpenAL Buffer 생성 ( 계속 ) size_t ov_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) return fread(ptr, size, nmemb, (FILE*)datasource); int ov_seek_func(void *datasource, ogg_int64_t offset, int whence) return fseek((file*)datasource, (long)offset, whence); int ov_close_func(void *datasource) return fclose((file*)datasource); long ov_tell_func(void *datasource) return ftell((file*)datasource); 20

8장예제 (PlayOggVorbis) 의중요함수들 OggVorbis 디코딩 // Ogg 스트림을디코딩하여 Wav PCM stream으로변환한다. unsigned long DecodeOggVorbis( OggVorbis_File *psoggvorbisfile, // 디코딩할 OggVorbis 스트림 char *pdecodebuffer, // 디코딩된 PCM Wav 데이터가저장될버퍼포인터 unsigned long ulbuffersize, // 디코딩된 PCM Wav 데이터가저장될버퍼의길이 ( 바이트 ) unsigned long ulchannels) // 채널수 ( 모노 (1), 스테레오 (2), Quad(4), 5.1(6)) int current_section; long ldecodesize; unsigned long ulsamples; short *psamples; unsigned long ulbytesdone = 0; while (1) ldecodesize = fn_ov_read(psoggvorbisfile, pdecodebuffer + ulbytesdone, ulbuffersize - ulbytesdone, 0, 2, 1, &current_section); if (ldecodesize > 0) ulbytesdone += ldecodesize; if (ulbytesdone >= ulbuffersize) break; else break; 21 8장예제 (PlayOggVorbis) 의중요함수들 OggVorbis 디코딩 ( 계속 ) // Mono, Stereo and 4-Channel files decode into the same channel order // as WAVEFORMATEXTENSIBLE, however 6-Channels files need to be re-ordered if (ulchannels == 6) psamples = (short*)pdecodebuffer; for (ulsamples = 0; ulsamples < (ulbuffersize>>1); ulsamples+=6) // WAVEFORMATEXTENSIBLE Order : FL, FR, FC, LFE, RL, RR // OggVorbis Order : FL, FC, FR, RL, RR, LFE Swap(pSamples[ulSamples+1], psamples[ulsamples+2]); Swap(pSamples[ulSamples+3], psamples[ulsamples+5]); Swap(pSamples[ulSamples+4], psamples[ulsamples+5]); return ulbytesdone; 22

ogg 샘플소스를이용하여.ogg 파일 2개를스트림재생하시오. 제출물 Full Comment가달린소스코드가포함된프로젝트폴더 프로그램제작설명서 제출기한 여기엔소스코드포함하면안됨. 5 월 9 일밤 12 시 Homework 23 Q & A 24