วันพฤหัสบดีที่ 21 เมษายน พ.ศ. 2554

การสังเคราะห์เสียงด้วย Chuck

ก่อนหน้านี้ได้ลองใช้ Puredata (pd) สังเคราะห์สัญญาณ Decay Sinusoid ซึ่งมีลักษณะเสียงคล้ายเสียงฆ้อง ตั้งใจว่าจะใช้สังเคราะห์เสียงดนตรีไทย แต่ว่าการใช้งาน Python ร่วมกับ Puredata แม้ว่าจะทำได้ แต่ดูเหมือนว่าจะทำได้ยาก เนื่องจากมีเอกสารกำกับน้อย น่าจะเหมาะกับคนที่ใช้ Python จนคล่องแคล่วแล้วมากกว่า

ผมก็เลยกลับมาพิจารณา Chuck อย่างจริงจังอีกครั้งหนึ่งหลังจากที่ได้เอาคู่มือมาพลิกผ่าน ๆ เมื่อหลายเดือนก่อนพบว่าน่าจะสามารถใช้งานร่วมกับ Python ได้ง่ายกว่า

Chuck คืออะไร
Chuck คือ Real-Time Audio Programming Language สำหรับงานสังเคราะห์และเรียบเรียงเสียงสังเคราะห์ โปรแกรมที่เขียนด้วย Chuck จะรันใน Chuck Virtual Machine ที่มีความสามารถในการรันหลาย ๆ โปรแกรม (Shred) ได้พร้อม ๆ กัน และแต่ละ Shred ก็สามารถสื่อสารเพื่อประสานงานกันได้ ท่านที่สนใจสามารถอ่านรายละเอียดเพิ่มเติมได้ที่ http://chuck.cs.princeton.edu/ และ http://kijjaz.exteen.com/20070702/entry (ภาษาไทย)

ตัวอย่างสคริปต์ที่รันใน Chuck

SinOsc s => dac;
440 => s.freq;
0.5 => s.gain;
2::second => now;

สคริปต์ข้างต้นนี้จะกระทำ 2 สิ่งคือ ต่อไซนูซอยด์ออสซิลเลเตอร์ (s) เข้ากับซาวด์การ์ด (dac) ตั้งค่าความถี่และขนาดสัญญาณเป็น 440 เฮิรทซ์และ 0.5 ตามลำดับ จากนั้นให้เวลาในสคริปต์เดินหน้าไป 2 วินาทีส่งผลให้เกิดเสียงขึ้น 2 วินาที

เรื่องเวลานี่ทีแรกผมไม่เข้าใจ แต่ถ้าเราเปรียบเทียบกับการเดินหน้าเส้นเทปไป 2 วินาทีก็จะเข้าใจง่ายขึ้น สัญญาณเสียงนั้นอยู่ในเทปอยู่แล้ว แต่ถ้าเส้นเทปไม่เดินผ่านหัวเทปก็จะไม่เกิดเสียงขึ้น

หลังจากเขียนสคริปต์เสร็จแล้วก็บันทึกไว้ในแฟ้มชื่อ foo.ck ก็ได้ (ตามขั้นตอนใน Tutorial เป๊ะ ๆ) ถ้าจะให้ Chuck ทำงานก็เรียกคำสั่ง

# chuck foo.ck

ก็จะได้ยินเสียงไซนูซอยด์ดังออกมาจากลำโพง

นอกจากนี้โปรแกรม Chuck ยังมี Built-in ฟังก์ชันและออบเจกต์ที่ใช้ประมวลผลสัญญาณเสียงอีกมากมาย ที่ใช้บ่อย ๆ ก็คงจะเป็นพวกตัวกรองต่าง ๆ ในงานที่ผมใช้สังเคราะห์เสียง Decay Sinusoid ที่มีเสียงคล้ายเสียงฆ้องนั้น เมื่อพิจารณาแล้วสามารถใช้ตัวกรองแบบ Bi-Quad ได้ การใช้ตัวกรอง Bi-Quad ใน Chuck สามารถทำได้ดังนี้

Impulse i => BiQuad f => dac;
0.000 => f.b0;
0.04128430 => f.b1;
0.000 => f.b2;
1.0000 => f.a0; 
-1.99824581 => f.a1;
0.99995098 => f.a2;

0.3 => i.next;
5::second => now;

ในสคริปต์นี้
  • บรรทัดแรกจะเรียกใช้ออบเจกต์อิมพัลส์และเชื่อมต่ออิมพัลส์เข้ากับตัวกรอง Bi-Quad และต่อเอาต์พุตจาก Bi-Quad เข้ากับซาวด์การ์ดของเรา 
  • บรรทัดที่ 2 - 7 ระบุค่า Coefficient ของตัวกรองทั้ง 6 ตัว 
  • บรรทัดที่ 8 ระบุขนาดของอิมพัลส์ที่จะส่งเข้าตัวกรอง
  • บรรทัดที่ 9 ระบุช่วงเวลาที่จะให้ Chuck ส่งเสียงออกมา
นี่คือเสียงสังเคราะห์ของฆ้องวงเล็กลูกแรก ผมบันทึกแฟ้มเป็น gong01.ck ถ้าต้องการให้ Chuck สร้างเสียงฆ้องลูกนี้ก็เรียกใช้คำสั่ง

# chuck gong01.ck

ก็จะได้ยินเสียงคล้าย ๆ เสียงฆ้องดังออกมา

จากที่ทดลองพบว่าการใช้ Chuck นั้นง่ายพอ ๆ กับ puredata แต่ว่าถ้าคิดถึงการเชื่อมต่อกับโปรแกรมอื่น ๆ เพื่อให้ทำงานร่วมกันหลังฉากโดยไม่ต้องให้ผู้ใช้งงกับหน้าต่างมาก ๆ โปรแกรม Chuck ดูเหมือนจะเป็นทางเลือกที่ดีกว่า ต่อไปนี้ก็จะลองใช้ Chuck เพื่อสังเคราะห์เสียงอื่น ๆ ต่อไปดู

ไม่มีความคิดเห็น: