“Max คือชุดซอฟต์แวร์สำหรับเขียนโปรแกรมด้านดนตรี โดยใช้กราฟฟิกแทนที่การเขียนด้วยตัวอักษร (Graphical Music Programming Environment) สำหรับผู้ที่แตะขีดจำกัดของซีเควนเซอร์หรือโปรแกรมที่ใช้กับอุปกรณ์ MIDI ตามท้องตลาด”
—Miller Puckette, Max reference manual, 1988
MSP (Max Signal Processing) คือชุดของออบเจกต์ที่เพิ่มเข้าไปบน Max สำหรับประมวลผลสัญญาณเสียง (Audio) เพื่อเพิ่มขีดจำกัดการทำงานของ Max ให้มีความสามารถด้านสัญญาณเสียงด้วย แทนที่จะมีแต่ MIDI เพียงอย่างเดียว
ตัวอย่าง Patch สำหรับ ทำ FM Synth อย่างง่าย
นั่นคือคำอธิบายฉบับย่อนะครับ ลองมาดูคำอธิบายอย่างยาว (ผมเขียนไว้นานแล้ว จะพยายามแก้ไขเรื่อย ๆ เพื่อให้เข้าใจได้ง่ายที่สุดครับ)
Max/Msp คือเครื่องมือสำหรับการสร้างโปรแกรมโดยที่เราไม่ต้องเรียนรู้ภาษา (Syntax) ใด ๆ การเขียนโปรแกรมเป็นเพียงการนำกล่อง (Object) ที่มีหน้าที่ต่าง ๆ กันตามชื่อของมัน มาเชื่อมต่อกันเพื่อให้โปรแกรมทำงานตามที่เราต้องการ ซึ่งชื่อ Max/Msp ประกอบไปด้วย 2 ส่วนคือ Max กับ Msp แยกกันตามหน้าที่ ซึ่งมาอยู่ในโครงสร้างเดียวกัน เลยเรียกรวมกันว่า Max/Msp
โดย Max คือกลุ่มของ Object ที่จัดการด้าน Midi (พูดง่าย ๆ ก็คือกล่องต่าง ๆ ที่ใช้งานด้าน MIDI นั้นเอง) เกิดขึ้นเพราะความต้องการของผู้ใช้ ที่ต้องการ Interactive Music (ดนตรีแบบตอบโต้ระหว่างผู้เล่นกับคอมพิวเตอร์)
Max สร้างในปี 1986 ที่ IRCAM (Institut de Recherche et de Coördination Acoustique/Musique) ซึ่งเป็นสถาบันวิจัยด้านอะคูสติกและดนตรีในปารีส โดยนาย Miller Puckette เพื่อนำมาใช้งานด้าน Interactive Music และนำออกมาจำหน่ายโดย Opcode Systems และพัฒนาต่อด้วยความร่วมมือกันของ Puckette และ David Zicarelly ในปี 1991ถึงวันนี้ก็ประมาณ 13 ปีแล้ว และนับตั้งแต่ Cycling’74 เป็นผู้พัฒนาและจำหน่ายต่อในปี 2000 จึงได้ออกเวอร์ชันสำหรับ Windows ด้วย
เราสามารถที่จะใช้ Max ควบคุมอุปกรณ์ MIDI อย่างที่เราต้องการได้ทุกอย่าง เพราะ Max ทำงานแบบ Real time เราจึงสามารถใช้ Max เขียนโปรแกรมเพื่อการ Composing, Improvising และเตรียม Accompaniment สำหรับการเล่น หรือเอาไว้ใช้ส่งคำสั่งไปที่เครื่อง Synthesizer หรือจะปรับแต่ง Patch ของเครื่อง Synth หรือสร้างแนวคิดใหม่ ๆ เกี่ยวกับ MIDI เท่าที่จินตนาการที่ไม่มีที่สิ้นสุดของมนุษย์จะไปถึง
Msp คือกลุ่ม Object ด้าน Signal Processing (การประมวลผลสัญญาณ) เกิดขึ้นในปี 1997 หลังจากที่คอมพิวเตอร์ Macintosh เร็วพอที่จะประมวลผลด้านสัญญาณเสียงได้ เพื่อจัดการด้าน Digital Audio โดยตรง พูดกันง่าย ๆ เลย หากคุณอยากสร้าง Reverb, Delay ขึ้นมาใช้ หรืออยากสร้าง Vocoder ในแบบที่ไม่เหมือนใคร ต้องใช้ Msp (ใช้ Max อย่างเดียวไม่ได้ เพราะ Max จัดการได้แค่ MIDI เท่านั้น จึงจำเป็นต้องใช้ร่วมกัน)
ขอบเขตการใช้งาน Max/Msp?
เพราะ Max/Msp อยู่บนพื้นฐานของภาษา C ครับ ทำให้เราสามารถที่จะเขียน Object ขึ้นมาใช้เองได้ ทำให้เราใช้งานได้อย่างไม่มีขอบเขต (หากเรารู้ภาษา C) นอกจากนี้ Max/Msp ยังสนับสนุน Rewire และ VST อีกด้วย เราจึงใช้ Max/Msp คู่กับ Reason หรืออะไรก็ตามที่สนับสนุน Rewire ทั้งยังใช้งาน Plug-in ที่เป็น VST ด้วย
การจะเขียนโปรแกรมด้วย Max จะต้องทำอย่างไรบ้าง?
เริ่มต้นต้องติดตั้ง Max/Msp ลงเครื่องเสียก่อน โดยสามารถดาว์นโหลดได้ที่ www.cycling74.com โดยจะมีเวลาให้ทดลองใช้ได้ 1 เดือนก่อนที่จะตัดสินใจซื้อ เมื่อติดตั้งเรียบร้อย ก็ปรับระบบ MIDI และ Audio ของเราให้เข้าที่เข้าทาง ต่อไปจะเริ่มอธิบายรูปแบบของการเขียนโปรแกรมด้วย Max นะครับ เริ่มกันเลย
Max/Msp เป็นการสร้างโปรแกรมที่เหมือนกับการวาดรูป เราจะมี Palette (จานสี) อย่างที่โปรแกรมพวก Paint หรือ Photoshop มี แล้วนำเอาอะไร ๆ ที่อยู่ในจานสี (Object) มาสร้าง ดังนั้น เราจึงจำเป็นต้องรู้จัก Objectต่าง ๆ นั้นก่อน หาอ่านได้ที่คู่มือที่ชื่อ Max Reference Manual ซึ่ง Object ด้าน MIDI ของ Max มีอยู่ประมาณ 200 กว่า Object และด้าน Signal Processing ของ Msp มีประมาณ 200 เช่นกัน เราจึงค่อย ๆ เรียนรู้กันไป ผมใช้วิธีที่คิดว่าเร็วที่สุด คือการเรียนรู้จากโปรแกรมที่สร้างมาจาก Max/Msp จริง ๆ โดยดูว่าโปรแกรมมันทำหน้าที่อะไร ทำงานอย่างไร โดยค่อย ๆ ทำความเข้าใจส่วนต่าง ๆ เริ่มจากส่วนที่เล็กที่สุด คือ Object แล้วค่อยขยายไปจนทั่วทั้งหมด เป็นการแกะโปรแกรมนั่นเอง การแกะโปรแกรมที่สร้างด้วย Object แบบนี้ ก็ยังดีกว่า แกะโปรแกรมที่สร้างมาจากภาษาระดับสูง หรือหากเป็นภาษาระดับล่างยิ่งไม่ต้องพูดกันเลย ซึ่งเป็นข้อดีของ Max/Msp อีกอย่างหนึ่ง เพราะทำให้เราได้เรียนรู้อะไรได้เร็ว
เชื่อมต่อระหว่าง Object
เส้นที่ใช้เชื่อมระหว่าง Object หรือที่เรียกกันว่า Patch Cord นั้น ทำหน้าที่ในการส่ง Message ให้กัน สังเกตเห็นจุดดำ ๆ ที่อยู่บนสุดของ Object จะเรียกว่า inlet ซึ่งใช้ในการรับ Message จาก Object อื่น ๆ และจุดดำ ๆ ที่อยู่ใต้สุดของ Object เรียกว่า Outlet มีไว้ส่ง Message ออกจาก Object โดย Message ก็จะมีหลายประเภทดังนี้ครับ
int ซึ่งก็หมายถึง Integer หรือจำนวนนับนั้นเอง เมื่อ Message เป็นตัวเลขอย่างเดียว (อย่างเช่น 127) Max จะจัดชนิดของ Message ให้เป็น int ทันที และจะส่งค่าต่อเป็น int 127
float เมื่อ Message นั้นเป็นตัวเลขที่มีจุดทศนิยม (อย่างเช่น 3.14 หรือ 3. หรือ .14) Max จะจัดให้เป็น Message แบบ float เพราะตัวจุดทศนิยมจะเป็นตัวบอกว่าเป็น int หรือ float ถึงกระนั้นก็ตาม Message ก็ยังจะส่งค่าออกไปเป็น float 3.14 อยู่ดี
list ก็คือกลุ่มของตัวเลข ที่เก็บตัวเลขมากกว่า 2 ตัวขึ้นไป โดยไม่จำกัดว่าจะเป็น int หรือ float หรือแม้จะเป็นตัวอักษร (อย่างเช่น “1 start 127”) Max ก็ยังจะจัด Message นี้เป็นแบบ list ขอเพียงขึ้นต้นด้วยตัวเลขและตัวหลังจะตามมาด้วยอะไรก็ได้
bang เป็น Message พิเศษกว่าแบบอื่น ๆ ครับ หากเปรียบเป็นภาษาคนก็คงจะบอกประมาณว่า “ทำตามหน้าที่ของนายไป” ยกตัวอย่างเช่น หากเราส่ง bang เข้าไปใน Object ที่ชื่อ Random มันจะทำการส่งตัวเลขออกจาก outlet เป็นแบบสุ่ม เริ่มรู้สึกสนุกแล้วใช่ไหมครับ
symbol คือคำหรือตัวอักษร (ไม่นับตัวเลข) ซึ่ง symbol ส่วนใหญ่จะเป็นคำที่มีความหมาย เพื่อใช้สื่อสารกับ Object แต่ไม่ได้หมายความว่า คำสั่งหนึ่งจะใช้ได้กับทุก object เราสามารถดูได้ว่าเราจะสามารถใช้ symbol อะไรกับ Object ต่าง ๆ ได้ที่ Max Reference Manual ครับ จะลองยกตัวอย่างให้เข้าใจ อย่าง Object ที่ชื่อ seq ซึ่งทำหน้าที่เป็น MIDI Sequencer สำหรับการบันทึกค่า MIDI เราจะสามารถส่ง Message ที่เป็นคำที่มีความหมายอย่าง start, stop, record, delay หรือ print แต่เราจะไม่สามารถส่ง symbol เหล่านี้ไปยัง Object * (เครื่องหมายคูณ) ซึ่งจะรับ Message ประเภทตัวเลขหรือ bang เท่านั้น
ใน Message อาจเป็นได้ทั้งตัวเลขและตัวอักษร หรือเป็นทั้ง 2 อย่าง บาง Object สามารถที่จะรับ Message ได้ทุกชนิด แต่ Object ส่วนใหญ่ จะรับได้แค่แบบเดียวจากที่กล่าวมา และจะไม่เข้าใจ Message ในแบบอื่น ๆ
จะเกิดอะไรขึ้นหาก Object รับ Message ที่มันไม่รู้จัก?
มันอาจวางเฉย หรือรายงานผลความผิดพลาดให้เรารู้บนหน้าต่าง Max ก็ได้ครับ ซึ่งในกรณีที่วางเฉย เป็นเรื่องที่น่าเบื่อสำหรับคนใช้ เพราะเราจะต้องมานั่งไล่หาสาเหตุกัน ซึ่งเป็นเรื่องเสียเวลา แต่ในกรณีส่วนใหญ่ เมื่อเราต่อ Patch Cord จาก outlet ของ Object หนึ่ง ไปสู่ inlet ของ Object หนึ่ง Max จะทำการวิเคราะห์ชนิดของ Message ที่จะทำการส่ง และจะไม่ให้เราต่อได้หาก Max รู้ว่า Object นั้นจะไม่รู้จัก Message ที่เราต้องการจะส่ง
จำนวน (Number)
อย่างที่บอกไว้ในหัวข้อที่แล้วว่า Max จะมีจำนวนอยู่สองแบบคือ int จำนวนนับ และ float จำนวนที่มีจุดทศนิยม ในการแปลงจากจำนวนแบบ float มาเป็นจำนวนแบบ int จะเป็นการตัดจำนวนหลังจุดทศนิยมทิ้งไป ไม่ได้ทำการเลือกที่จะปัดขึ้นหรือปัดลงอย่างที่เรา ๆ ท่าน ๆ คุ้นเคย อย่างเช่น จำนวน 4.1 เมื่อทำเป็น int ก็จะได้ 4 เช่นเดียวกับ จำนวน 4.999 เมื่อแปลงเป็น int ก็จะได้ 4 เช่นเดียวกัน
ในการเขียนโปรแกรมด้าน MIDI เราจะใช้จำนวนแบบ int และในการเขียนโปรแกรมด้าน Digital Audio จะใช้จำนวนแบบ float ส่วนในเรื่องของเวลาซึ่งใน Max เราจะวัดเป็นมิลลิวินาทีซึ่งเราจะใช้ int หรือ float ก็ได้
เราสามารถแทนจำนวนแบบ int ด้วยจำนวนเลขฐาน 16 (hexadecimal number) ก็ได้ ซึ่งในทาง MIDI นิยมใช้รูปของเลขฐาน 16 ในการระบุค่าต่าง ๆ รวมถึงอะไรก็ตามที่เกี่ยวข้องกับคอมพิวเตอร์ด้วยเพราะสะดวกในการแตกออกเป็นเลขฐานสอง ซึ่งเป็นระบบเลขที่คอมพิวเตอร์ในปัจจุบันใช้สื่อสารและประมวลผล
ในการใช้เลขฐาน 16 ใน Max เราต้องใส่ 0x (ศูนย์กับตัว x) นำหน้าด้วย อย่างเช่น 0xF4 (มีค่าเท่ากับ 244 ในเลขฐาน 10)
ลำดับของการส่ง Message
Object ส่วนใหญ่จะมีหลาย outlet และจะส่ง Message ออกไปพร้อมกันทุก outlet แต่ในความเป็นจริงแล้ว การทำงานของ Max ไม่มีอะไรที่เกิดขึ้นพร้อมกันครับ ทุกอย่างเกิดขึ้นเร็วมากจนเรารู้สึกว่ามันทำงานพร้อมกัน แต่ก็เป็นเรื่องสำคัญที่ผู้ใช้งาน จำเป็นต้องรู้ลำดับของการส่ง Message ก่อนหลัง
การส่ง Message ที่ดูเหมือนจะเป็นการส่งพร้อมกันนั้น การเรียงลำดับของมันจะเป็นการเรียงจากขวามาซ้าย โดย outlet ด้านขวาสุดจะส่งออกไปก่อน และ outlet ที่อยู่ถัดมาทางซ้ายก็จะส่งออกและก็ไล่มาทางซ้ายเรื่อย ๆ ซึ่งในทุก Object ของ Max ก็ใช้หลักการส่งอันเดียวกันนี้
ในรูปซ้ายมือจะเป็นการแสดงลำดับของการส่ง Message ที่เรียงจากขวาไปซ้าย ส่วนรูปขวามือ จะเห็นว่าเป็นการเชื่อมต่อจาก outlet เดียว ไปยังหลาย ๆ object ซึ่งยังคงหลักการเดิมคือ ขวาไปซ้าย แต่เมื่อ object มีการวางตามขวางที่เท่ากันพอดี การส่ง message จะไล่จาก object ล่างก่อน แล้วจึงเป็น object บน และหาก 1 outlet เชื่อมต่อกับ 2 inlet ของ object เดียวกัน ก็ยังใช้หลักการเดิมคือ ขวาไปซ้าย
ในทางเดียวกัน เมื่อ object ใด ๆ ที่มีมากกว่า 1 inlet จะมีการรับ message ที่ไล่จากขวาไปซ้ายเช่นกัน และมันจะเก็บ message นั้น ๆ ไว้ จนกว่า inlet ที่อยู่ซ้ายมือสุด ซึ่งพอ inlet ซ้ายมือสุดได้รับ message แล้ว object จึงจะทำตามหน้าที่ของมัน ก่อนที่จะส่ง message ออกทาง outlet ต่อไป ท่านผู้อ่านหลาย ๆ คนจะรู้สึกได้เลยว่า inlet ที่อยู่ซ้ายสุดนั้นทำหน้าที่เหมือนเป็นตัว trigger object นั้นไปด้วยนั่นเอง ซึ่งในความจริงแล้วก็จะมีบาง object ที่ไม่ได้เป็นไปตามนี้ แต่ object เกือบทั้งหมดที่มีใน Max/Msp ต่างก็ใช้ inlet ซ้ายสุด เป็นตัว trigger
ในบาง object ที่สามารถรับ message ที่เป็น list ของจำนวน บน inlet ที่อยู่ซ้ายสุด และจะให้ผลเหมือนกับการที่ object นั้นรับค่า inlet จากขวาไปซ้าย
สรุป เมื่อ object ส่ง message ออกไป ก็จะไป trigger object ที่รับ message นั้น เพื่อประมวลผล แล้วส่ง message ออกไปสู่ object ต่อไป และเป็นแบบนี้ไปเรื่อย ๆ จนกว่าจะสิ้นสุดการกระทำใด ๆ Max จะกลับไป Object เริ่มต้น เพื่อส่ง message ต่อไป
จากตัวอย่างข้างล่างจะเห็นว่า ในขั้นตอนที่ 3, 4, 5 จะกระทำไปจนกว่าไม่มี message ไหน มา trigger และจะมี message มา trigger inlet ขวาสุดของ object บวก