เล่น file ogg แบบ stream ให้ loop เนียนไร้รอยต่อ (ผ่าน SDL)

คราวนี้ขอแปะแต่โค๊ดก่อนนะครับ อธิบายจะตามมาวันหลัง ง่วงแล้ว (ตีสองครึ่งแล้วนะ !!)

ที่ว่าแบบ stream ก็คือ จะไม่อ่านทีเดียวทั้งไฟล์ เก็บไว้ในเมมโมรี่ก่อน (มันเปลือง) แต่จะใช้วิธีค่อย ๆ บัฟเฟอร์ไฟล์มาเก็บไว้ แล้วค่อย ๆ เล่นทีละส่วน (ซึ่งเป็นเทคนิคทีเรียกว่าการทำ streaming)

หลักการคร่าว ๆ ก็คือ

  1. เติมข้อมูลทุก ๆ บัฟเฟอร์ เว้นบัฟเฟอร์สุดท้ายไว้ (จริง ๆ ไม่ต้องเว้นก็ได้ แต่ที่เว้นเพื่อความสะดวกในการเขียนโค้ด)
  2. เมื่อบัฟเฟอร์แรกถูกเล่น บัฟเฟอร์สุดท้ายจะถูกเติมข้อมูล
  3. เมื่อบัฟเฟอรฺ์แรกหมด จะมีการเรียก call back จากระบบมาบอกว่าเล่นบัฟเฟอร์หมดแล้ว ให้ก๊อปบัฟเฟอร์ที่สองใส่บัฟเฟอร์ระบบไป แล้วเติมบัฟเฟอร์แรกที่เล่นจบไปแล้ว
  4. ถ้าหากระหว่างเติมบัฟเฟอร์ ดันจบเพลงซะก่อน ก็ seek ไปยังตำแหน่งเริ่มต้น loop ใหม่ซะ แล้วบัฟเฟอร์ต่อจนเต็ม

เอาแค่นี้ก่อนละกัน เดี๋ยวค่อยมาแก้เพิ่มครับ 🙂

#include 
#include 

#include 
#include 

const int BUFFER_COUNT = 6;
const int NUM_SAMPLE = 4096*4;
const int BUFFER_SIZE = 2 * 2 * NUM_SAMPLE; //2 channels * 2byte per sample * NUM_SAMPLE

int current_buffer = 0;
char bgm_buffer[BUFFER_COUNT][BUFFER_SIZE];

const int loop_start = 291784;  // loop point in #sample, this is song-specific setting
								// and suits only for supplied ogg file.
								// Updates this value to test with other file.

SDL_mutex *mutex;
OggVorbis_File file;


// Macros for a lazy guy like me :P
#define if_error_display_then_exit(x, y)  
	if( (x) != 0 ) { std::cout<<(y)<

ต่อไปก็ Source Code กับตัวโปรแกรมนะครับ
Source
Binary

ตัวโปรแกรม (น่าจะ) ต้องใช้กับ VS 2008 Runtime นะครับ ถ้าไม่มีก็คงรันไม่ได้มั้ง ??? แต่ก็เอาโค๊ดไปคอมไพล์เองเป็นเวอร์ชั่นอื่นก็ได้ครับ

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

This site uses Akismet to reduce spam. Learn how your comment data is processed.