- มีข้อจำกัดด้านคุณภาพของการบันทึกเสียงและ
- ไม่สามารถปรับค่าความถี่และอัตราลดทอนของเสียงได้
ผมได้ทดลองใช้ Chuck กับ Python เพื่อสังเคราะห์เสียงบน Linux ดูแล้วก็ใช้งานได้สะดวกดี แต่ Chuck ไม่มีเครื่องมือที่จะเชื่อมต่อกับ Java และ Android (หรือมีแต่ผมหาไม่เจอ) ส่วน Csound นั้นผมไม่เคยใช้ ค้นดูก็ไม่เจอเครื่องมือที่จะเชื่อมต่อกับ Java และ Android เช่นกัน
สำหรับ puredata นั้นเดิมผมเคยยอมแพ้มันมาแล้วหนหนึ่งด้วยเหตุว่าเขียนแพตช์ (Patch) ของ puredata ไปแล้วก็เอาไปใช้ในโปรแกรมอื่นเหมือน Chuck ไม่ได้...จนกระทั่งผมได้พบกับ libpd จึงได้ทราบว่าผมคิดผิด
อันที่จริง puredata สามารถสื่อสารกับภาษาโปรแกรมอื่น ๆ ได้ผ่านทาง libpd ขั้นตอนการพัฒนาโปรแกรมโดยใช้ libpd จะเป็นดังนี้
- ผู้พัฒนาจะสร้างแพตช์ puredata ขึ้นมาก่อน โดยกำหนดชื่อตัวแปรควบคุมไว้แทนอินเลต
- เปิดแพตช์ที่สร้างขึ้นจากคำสั่ง openPatch
- ส่ง Bang Float Message ผ่านคำสั่ง sendBang sendFloat และ sendMessage ไปยังแพตช์เป้าหมายตามลำดับ
การสังเคราะห์เสียงฆ้องด้วย pd
จากการวิเคราะห์เสียงฆ้องในเบื้องต้นพบว่าคุณลักษณะพื้นฐานที่โดดเด่นของเสียงฆ้องคือองค์ประกอบ Exponentially Decayed Sinusoid ซึ่งสามารถสร้างได้โดยแพตช์ดังแสดงในรูป
andgong.pd |
amath f(t)=e^{-2t} endamath
ส่วนตัวเลขความถี่ที่ป้อนเข้ามาแต่แรกก็จะไปกระตุ้น [osc~] เพื่อให้สร้างสัญญาณไซนูซอยด์ออกมา เมื่อนำมาคูณกับเอกโพเนนเชียลในตอนแรกและคูณกับ 0.3 ก่อนส่งออกทางเอาต์เลตจะทำให้ได้ฟังก์ชัน
amath g(t) = 0.3 e^{-2t} cos(2\pi f t) endamath
จะเป็นเสียงฆ้องลูกทวนหรือว่าลูกยอดก็แล้วแต่ว่าความถี่ที่ป้อนเข้าทางอินเลตนั้นเป็นเท่าใด
แต่ [timearray] ไม่ใช่ออบเจกต์มาตรฐานของ pd แต่เป็นออบเจกต์ที่ผมสร้างขึ้นมาเองเพื่อสร้างตัวแปร t ที่วิ่งจาก 0 ถึง 5000 ในเวลา 5 วินาที (ขั้นละ 1 มิลลิวินาที) ทุกครั้งที่มีการกระตุ้นออบเจกต์ด้วย [bang( ซึ่งกลไกของ [timearray] แสดงดังรูปต่อไปนี้
timearray.pd |
เมื่อมี [bang( เข้ามาทางอินเลต ข้อความ 0 จะถูกกระตุ้นเพื่อส่งให้ [line~] กระโดดจากค่าใด ๆ ก็ตามขณะนั้นไปที่ [0( ทันที หลังจากนั้น 1 มิลลิวินาที [bang( ที่ถูกหน่วงเวลาไว้ก็จะกระตุ้นข้อความ [5 5000( เพื่อส่งให้ [line~] ทำให้เอาต์พุตของ [line~] เปลี่ยนแปลงจาก 0 ไปเป็น 5 ภายในเวลา 5000 มิลลิวินาที นั่นหมายความว่าเอาต์เลตของแพตช์นี้ก็คือค่าเวลาเป็นวินาทีขั้นละ 1 มิลลิวินาทีเป็นเวลา 5 วินาทีนั่นเอง
เนื่องจาก libpd อนุญาตให้มีแพตช์ Instance เดียว เราก็เลยต้องสร้างลูกฆ้องทั้ง 16 ลูกในแพตช์โดยให้ฆ้องแต่ละลูกถูกกระตุ้นโดยตัวแปร h01 - h16 ด้วยตัวเลขค่าความถี่
gongwong.pd |
แม้ว่าจะตีฆ้องทีละลูกหรืออย่างมาก 2 ลูก เพื่อให้การเชื่อมต่อสัญญาณกับ [dac~] ไม่ติดขัดเพราะเชื่อมกับอินพุตมากเกินไปเราเลยใช้ [+~] รวมสัญญาณจากฆ้องแต่ละลูกเข้าด้วยกัน แต่ Hot Inlet คืออินเลตทางซ้ายเท่านั้น เราเลยต้องให้ตัวแปรความถี่ลูกฆ้องลูกที่ 2 - 16 กระตุ้น [bang( เพื่อกระตุ้น Hot Inlet ของ [+~] ตัวแรกด้วย นอกจากนี้ก่อนจะส่งสัญญาณเสียงออกมาทาง [dac~] เราจะป้องกันองค์ประกอบไฟตรง (DC Component) โดยใช้ตัวกรองความถี่สูงผ่าน [hip~] โดยตั้งค่าความถี่ตัดไว้ที่ 1 เฮิร์ทซ และป้องกันการทำงานผิดพลาดของ libpd โดยการขริบสัญญาณขาออกไว้ให้ไม่เกิน +/- 1
เราสามารถทดสอบแพตช์ gongwong.pd ใน puredata ได้โดยการเปลี่ยน [r h01] ถึง [r h16] ให้เป็นข้อความ [xxx01( - [xxx16( รวม 16 ข้อความเมื่อ xxx01 - xxx16 คือค่าความถี่เสียงที่เราต้องการ และทดลองฟังเสียงโดยการคลิ๊กที่ข้อความแต่ละข้อความนั้น ๆ
เมื่อเราเตรียมแพตช์ของเราเรียบร้อยแล้ว ในตอนต่อไปเราจะมาดูว่าจะสามารถเรียกใช้แพตช์นี้ผ่าน libpd เพื่อเขียนโปรแกรมสำหรับแอนดรอยด์ได้อย่างไร