การเขียนโปรแกรมด้วย PocketC# ตอนที่ 7 – Sound

สำหรับตอนที่ 7 นี้ เรามาลองสร้างเสียงออกทาง pocketPC ของเราครับ

คำสั่งพื้นฐานของ C# จะไม่มีคำสั่งในการสร้างเสียงเลยครับ ซึ่งนับว่าเป็นเรื่องที่น่าแปลกใจเป็นอย่างยิ่ง เพราะการใช้งานคอมพิวเตอร์ทุกวันนี้ภาพและเสียงถือเป็นมาตรฐานที่ทุกเครื่องต้องมีอยู่แล้ว แม้ C# มีคำสั่งในการสร้างภาพ Graphics ที่มีประสิทธิภาพ แต่ในเรื่องเสียงแล้วไม่มี แม้แต่คำสั่งให้สร้างเสียงเตือน Beep ง่าย ๆ ดังนั้น หากต้องการให้โปรแกรมของเรามีเสียงเตือน ก็จะต้องใช้วิธีการพิเศษในการสร้างคำสั่งเกี่ยวกับเสียงครับ

C# มีวิธีการพิเศษในการเรียกใช้คำสั่งที่มีอยู่ใน ROM หรือ dll ไฟล์ ของ PocketPC เรียกว่า Platform Invoke หรือ P/Invoke วิธีการนี้จะเรียกใช้ไฟล์ dll ซึ่งบรรจุคำสั่งต่าง ๆ ที่ใช้ใน PocketPC เช่น คำสั่งให้เล่นไฟล์เสียง คำสั่งหมุนโทรศัพท์ คำสั่งเรียกใช้นาฬิกาภายในเครื่อง แล้วมาสร้างเป็นคำสั่งใหม่ที่ C# สามารถเรียกใช้ได้เหมือนเป็นคำสั่งปกติ ทำให้ทุ่นเวลาในการเขียนคำสั่งทั้งหมดขึ้นเองเพื่อให้ได้ผลตามต้องการ แต่ปัญหาก็คือว่าเราไม่รู้ว่าใน ROM ของ PocketPC มีไฟล์ dll ไหนที่เราสามารถเรียกใช้ได้บ้าง และในไฟล์ dll นั้น มีคำสั่งและวิธีเรียกใช้คำสั่งนั้นอย่างไร ซึ่งเรื่องนี้เพื่อน ๆ คงต้องค้นหากันเอาเองใน internet แหละครับ เพราะในที่นี้ผมจะนำเสนอเฉพาะคำสั่งในการเล่นไฟล์เสียง .wav เท่านั้นครับ

There is no Sound function in C#.NET ,but you can use P/Invoke technique to get Sound functions in ROM.

การใช้ P/Invoke ได้นั้น จะต้องอ้างถึงกลุ่มคำสั่งภายใน System.Runtime.InteropServices ดังนั้นจึงต้องเพิ่มการใช้กลุ่มคำสั่งนี้ด้วยคำสั่ง using ขอให้เพื่อน ๆ เปิดโปรแกรม graphic.cs แล้วเพิ่มบรรทัดนี้ลงไปในส่วนหัวของโปรแกรม

using System.Runtime.InteropServices;

คำสั่งในการสร้างเสียงจะอยู่ใน dll ของ ROM ใน PocketPC ที่ชื่อว่า coredll.dll ชื่อว่าคำสั่ง PlaySound การที่จะอ้างอิงคำสั่งใน dll ได้นั้น จะต้องเพิ่มคำสั่งเพื่อเรียกใช้ไฟล์ dll ที่ต้องการ และอ้างอิงไปยังคำสั่งนั้นพร้อมตัวแปรที่เกี่ยวข้อง โดยเพิ่มในส่วนของ class จากนั้นจึงจะสามารถใช้ method เรียกใช้คำสั่งนั้นได้ ขอให้เพื่อน ๆ เพิ่มคำสั่งนี้ลงใน class grx : Form ของเรา โดยการประกาศเรียกใช้ coredll ดังนี้

…

class grx : Form

{

//Graphics declaration

Graphics gr;

//Sound P/Invoke

[DLLImport(“coredll”,EntyPoint=”PlaySound”,SetLastError=true)]

private extern static bool PlaySound(String lpzName,int hModule,int dwFlags);

…

Use DLLImport to call PlaySound fuction in coredll.dll in ROM. The PlaySound function can play wave files only. In Playsound, String lpzName is filename, int hModule is any integer number, and int dwFlags is integer number flags. For hModule you can use 0. For dwFlags, 0 means play and wait until finish playing before doing next command (Synchronous) and 1 means play a wave file and do next command instantly (Asynchronous).

คำสั่ง DLLImport จะเป็นการเรียกใช้คำสั่ง PlaySound ภายใน coredll ซึ่งอยู่ภายใน ROM โดยคำสั่ง PlaySound จะรับตัวแปร string คือชื่อไฟล์เสียงที่มีนามสกุล wav เท่านั้น ซึ่งจะต้องระบุทั้ง directiory และ fiename แต่ไม่จำเป็นต้องระบุ extention คือ wav หากระบุแต่ filename อย่างเดียวจะหมายถึงไฟล์เสียงที่อยู่ใน ROM หรือใน Root directory เช่นเดียวกับการอ้างอิงไฟล์ภาพที่กล่าวในบทก่อน ๆ ครับ ส่วน int hModule จะเป็นค่าตัวเลขจำนวนเต็มใด ๆ ปกติจะใช้ค่า = 0 สำหรับ int dwFlags จะเป็นตัวบอกหน้าที่ของ PlaySound ปกติมีค่า = 0 หมายถึงเล่นไฟล์เสียงให้จบก่อนจึงจะทำงานคำสั่งต่อไป แต่หากตั้งค่าเป็น 1 จะหมายถึงให้ทำคำสั่งต่อไปทันทีแม้ว่าจะยังเล่นไฟล์เสียงไม่จบ

Add PlaySound(..) in OnMouseMove(..) method.

ขอให้เพื่อน ๆ ลองเพิ่มคำสั่งต่อไปนี้ภายใน method OnMouseMove(..) ของเราครับ

protected override void OnMouseMove(MouseEventArgs e)

{

PlaySound(“notify”,0,1);

Gr.FillEllipse(new SolidBrush(Color.Red),e.X,e.Y,10,10);

}

 

“notify” is notify.wav that is already in ROM. You can try another Wave files such as Windows Default , Alarm1, Alarm2, Infbeg, Infend, Lowbatt, msgbox etc. or use your own Wave files.

ไฟล์ชื่อ notify.wav เป็นไฟล์เสียงที่อยู่ใน ROM อยู่แล้วครับ เพื่อน ๆ ไม่ต้องสร้างไฟล์นี้ขึ้นมาแต่อย่างใด เพื่อน ๆ อาจจะใช้เสียงอื่น ๆ เช่น Windows Default, busy, Alarm1, Alarm2, Infbeg, Infend, Lowbatt, msgbox ฯลฯ ซึ่งไฟล์เสียงใน ROM นี้หาดูได้ใน Windows directory และอาจแตกต่างกันในเครื่องแต่ละยี่ห้อครับ

Build and Run, touch and move your stylus on screen. You will hear notify sound asynchronously.

จากนั้นก็ build และ run แล้วลองลากปากกาลงบนหน้าจอเพื่อวาดเส้น จะได้ยินเสียง notify ติด ๆ กันไปอย่างต่อเนื่องจนกว่าจะยกปากกาขึ้นจึงจะได้ยินเสียงครบถ้วน

จากนั้นลองเปลี่ยนคำสั่งเป็น

PlaySound(“notify”,0,0);

Try to play it synchronousely.

แล้วลอง build และ run ใหม่ เมื่อลากปากกาลงไปจะได้ยินเสียง notify ทีละเสียงจนจบก่อนจึงจะกำหนดจุดลงบนจอภาพ จึงทำให้เป็นจุด ๆ ขาด ๆ หาย ๆ ไม่ต่อเนื่อง

เพื่อน ๆ อาจจะลองใช้คำสั่ง PlaySound เรียกฟังไฟล์เสียงใน directory อื่น ๆ ได้ตามต้องการครับ เช่น PlaySound(“\\pc#\\mysound”,0,1); หรือลองเขียนโปรแกรมโดยใช้ OpenFileDialog() ตามที่กล่าวในตอนก่อน ๆ เพื่อเลือกไฟล์เสียงมาฟังได้ตามต้องการครับ

You can use OpenFileDialog to select wave files.

 

คำสั่ง PlaySound นี้ใช้ได้กับไฟล์ wav เท่านั้นนะครับ ไม่สามารถเรียกฟังไฟล์ wma, mp3 ได้ครับ

You can not use PlaySound with wma or mp3 files.

ในตอนต่อไปเราจะใช้ความรู้จากการเขียนโปรแกรมที่เราได้ศึกษามาทั้งหมด มาลองเขียนโปรแกรมเกมเล่นกันสักเกมครับ

Next time, I will try to write a Game Program.

ขอให้สนุกครับ

[email protected]

19 สิงหาคม 2550

 

 

 

 

 

Hosted by www.Geocities.ws

1