|
แผนผังบ้านแมว หน้าบ้านห้องทดลองมุมสงบห้องภาพห้องเก็บของห้องเขียนหนังสือท่องเที่ยวบันทึกแมวๆโครงงานเกี่ยวกับบ้านแมวลิงก์ ค้นหา Blog Feed :: Atom Follow :: Twitter GPG :: 5F830E4A |
MIDI SoftSynth บนลินุกซ์ด้วย ALSA VirMIDI + TiMidityIssued: 2003-05-04ปัญหานึงของซาวด์การ์ดหลายๆ รุ่นคือไม่มีมิดี้ที่เป็นฮาร์ดแวร์ หรือ FM Synth ก็เลยไม่สามารถเล่นมิดี้บนลินุกซ์ได้ (ถ้าเป็นวินโดวส์ ไดรเวอร์จะจำลองมิดิ้ให้ เป็นซอฟต์ซินธ์ด้วย (SoftSynth/Software Wave Table Emulation) แต่นับว่าโชคดีที่ลินุกซ์ทะเลใช้ระบบเสียงของ ALSA (Advanced Linux Sound Architecture) ก็เลยมีทางที่จะเซ็ตซอฟต์ซินธ์บลินุกซ์ด้วยเหมือนกันโดยใช้ไดรเวอร์ Virtual MIDI และซอฟต์แวร์ชื่อ TiMidity++ ... ขั้นตอนมีดังนี้ครับ เริ่มกันที่ ALSAคอมไฟล์ alsa-driver โดยระบุให้สร้างไดรเวอร์ virmidi ด้วย ถ้าติดตั้งลินุกซ์ทะเลปกติ จะมีไดรเวอร์นี้อยู่แล้ว แต่สำหรับคนที่ recompile alsa-driver ใหม่ถ้าระบุออพชั่น --with-cards ให้ใส่ virmidi เข้าไปด้วยประมาณนี้ ./configure --with-sequencer=yes --with-oss=yes --with-cards=virmidi,intel8x0 จากนั้นก็ make และ make install ตามปกติ หลังจากติดตั้ง alsa-driver แล้ว ทีนี้ก็ลอง load kernel module กัน .. [kitt@peorth kitt]$ modprobe snd-virmidi index=1 ถ้า lsmod ดูควรจะเห็นอะไรประมาณนี้ snd-virmidi 2144 0 (autoclean) snd-seq-virmidi 5096 0 (autoclean) [snd-virmidi] snd-seq-midi-event 5672 0 (autoclean) [snd-seq-virmidi] snd-seq 47408 0 (autoclean) [snd-seq-virmidi snd-seq-midi-event] snd-intel8x0 24228 1 snd-pcm 83360 0 [snd-intel8x0] snd-timer 19688 0 [snd-seq snd-pcm] snd-ac97-codec 44640 0 [snd-intel8x0] snd-page-alloc 8552 0 [snd-intel8x0 snd-pcm] snd-mpu401-uart 5184 0 [snd-intel8x0] snd-rawmidi 18752 0 [snd-seq-virmidi snd-mpu401-uart] snd-seq-device 6364 0 [snd-seq snd-rawmidi] snd 43332 0 [snd-mixer-oss snd-virmidi snd-seq-virmidi snd-seq-midi-event snd-seq snd-intel8x0 snd-pcm snd-timer snd-ac97-codec snd-mpu401-uart snd-rawmidi snd-seq-device] ลองสั่ง cat /proc/asound/cards
[kitt@peorth kitt]$ cat /proc/asound/cards
0 [82801CAICH3 ]: ICH - Intel 82801CA-ICH3
Intel 82801CA-ICH3 at 0x9800, irq 10
1 [VirMIDI ]: VirMIDI - VirMIDI
Virtual MIDI Card 1
จะเห็นว่ามีซาวด์การ์ดสองใบ หนึ่งในนั้นเป็นซาวด์การ์ดจริง (ในตัวอย่างนี้คือ 82801CA ICH3 ของชิพเซ็ต i830) อีกตัวเป็น VirMIDI เป็นการ์ดที่จำลองขึ้นมาโดย module snd-virmidi .. TiMidityที่จริงลินุกซ์ทะเลให้ TiMidity++ มาด้วยนะครับ แต่ว่าไม่ได้คอมไพล์ให้ใช้กับ ALSA ได้ .. ก็ต้องดาวน์โหลดเวอร์ชันที่คอมไพล์ ALSA และ ALSA Sequencer Client ด้วย .. ไม่ต้องไปหาไกล ผมทำให้แล้วล่ะ คิดว่าคงอยู่ใน TLE Update แล้ว จะใช้ Synaptic หรือจะสั่ง apt-get install หรือ apt-get update/upgrade เอาก็ได้ หรือดาวน์โหลด rpm ก็ได้ที่ ftp://ftp.kitty.in.th/pub/rpms/timidity++-2.11.3-4_1kit.i386.rpm เชื่อม Virtual MIDI กับ TiMidityVirtual MIDI ไม่ได้เล่นมิดี้ได้ด้วยตัวเองครับ มันแค่จำลองเป็นมิดี้อินเทอร์เฟซเท่านั้น จะทำให้มันเล่นมิดี้ มีเสียงได้ต้องทำให้ Virtual MIDI ส่งข้อมูลมิดี้ไปยัง TiMidity++ ให้ได้เสียก่อน .. อืมม จะอธิบายหลักการตรงนี้ก็เป็นเรื่องยาว .. ขอตัดบทเลยก็แล้วกัน ก่อนอื่น TiMidity++ เป็นโหมด ALSA Sequencer Client โดยระบุออพชัน -iA เข้าไป [kitt@peorth kitt]$ timidity -iA -Os & [1] 1106 Requested buffer size 32768, fragment size 8192 ALSA pcm 'default' set buffer size 32768, period size 8192 bytes TiMidity starting in ALSA server mode can't set sched_setscheduler - using normal priority Opening sequencer port: 128:0 128:1 จากนั้นหาหมายเลขพอร์ตของ Virtual MIDI โดยดูจากไฟล์ /proc/asound/clients หรือ /proc/asound/seq/clients
[kitt@peorth kitt]$ cat /proc/asound/seq/clients
Client info
cur clients : 6
peak clients : 6
max clients : 192
Client 0 : "System" [Kernel]
Port 0 : "Timer" (Rwe-)
Port 1 : "Announce" (R-e-)
Client 72 : "Virtual Raw MIDI 1-0" [Kernel]
Port 0 : "VirMIDI 1-0" (RWeX)
Client 73 : "Virtual Raw MIDI 1-1" [Kernel]
Port 0 : "VirMIDI 1-1" (RWeX)
Client 74 : "Virtual Raw MIDI 1-2" [Kernel]
Port 0 : "VirMIDI 1-2" (RWeX)
Client 75 : "Virtual Raw MIDI 1-3" [Kernel]
Port 0 : "VirMIDI 1-3" (RWeX)
Client 128 : "Client-128" [User]
Port 0 : "TiMidity port 0" (-We-)
Port 1 : "TiMidity port 1" (-We-)
Output pool :
Pool size : 500
Cells in use : 0
Peak cells in use : 0
Alloc success : 0
Alloc failures : 0
Input pool :
Pool size : 1000
Cells in use : 0
Peak cells in use : 0
Alloc success : 0
Alloc failures : 0
จะเห็นว่ามี Virtual RAW MIDI อยู่ 4 ไคลเอนด์ หมายเลข 72, 73, 74 และ 75 ตามลำดับ ทุกตัวมีพอร์ต 0 ... ส่วน TiMidity++ อยู่ที่ 128 มีสองพอร์ตคือ 0 และ 1 .. เมื่อได้หมายเลขพอร์ตแล้วก็สั่งเชื่อมพอร์ตได้แล้ว ที่ต้องทำก็คือเชื่อมพอร์ต 0 ของ Virtual RAW MIDI ตัวแรก เข้าไปที่พอร์ต 0 ของ TiMidity++ โดยคำสั่ง aconnect [kitt@peorth kitt]$ aconnect 72:0 128:0 ดู /proc/asound/seq/clients อีกครั้ง
[kitt@peorth kitt]$ cat /proc/asound/seq/clients
Client info
cur clients : 6
peak clients : 7
max clients : 192
Client 0 : "System" [Kernel]
Port 0 : "Timer" (Rwe-)
Port 1 : "Announce" (R-e-)
Client 72 : "Virtual Raw MIDI 1-0" [Kernel]
Port 0 : "VirMIDI 1-0" (RWeX)
Connecting To: 128:0
Client 73 : "Virtual Raw MIDI 1-1" [Kernel]
Port 0 : "VirMIDI 1-1" (RWeX)
Client 74 : "Virtual Raw MIDI 1-2" [Kernel]
Port 0 : "VirMIDI 1-2" (RWeX)
Client 75 : "Virtual Raw MIDI 1-3" [Kernel]
Port 0 : "VirMIDI 1-3" (RWeX)
Client 128 : "Client-128" [User]
Port 0 : "TiMidity port 0" (-We-)
Connected From: 72:0
Port 1 : "TiMidity port 1" (-We-)
Output pool :
Pool size : 500
Cells in use : 0
Peak cells in use : 0
Alloc success : 0
Alloc failures : 0
Input pool :
Pool size : 1000
Cells in use : 0
Peak cells in use : 1
Alloc success : 1
Alloc failures : 0
จะเห็นว่า Client 72 มีข้อความ Connected To: 128:0 และที่ TiMidity++ มีข้อความ Connected From: 72:0 คอนฟิกระบบถ้าต้องการคอนฟิกให้ลินุกซ์เรียก Virtual MIDI อัตโนมัติทุกครั้งที่บูตก็สามารถทำได้โดยแก้ /etc/modules.conf ประมาณนี้ alias snd-card-0 snd-intel8x0 alias snd-card-1 snd-virmidi alias sound-slot-0 snd-card-0 alias sound-slot-1 snd-card-1 alias char-major-116 snd alias char-major-14 soundcore options snd major=116 cards_limit=2 options snd-intel8x0 index=0 options snd-virmidi index=1 alias sound-service-0-0 snd-mixer-oss alias sound-service-0-1 snd-seq-oss alias sound-service-0-3 snd-pcm-oss alias sound-service-0-8 snd-seq-oss alias sound-service-0-12 snd-pcm-oss ที่ต้องเพิ่มเข้าไปใน /etc/modules.conf ก็คือ บรรทัด alias snd-card-1 snd-virmidi alias sound-slot-1 snd-card-1 options snd-virmidi index=1 และต้องเปลี่ยน cards_limit เป็น 2 ทีนี้ทุกครั้งที่บูต snd-virmidi module ก็จะได้รับการติดตั้งอัตโนมัติ ส่วนการเชื่อม Virtual MIDI กับ TiMidity++ ทำเป็นครั้งๆ ไปเมื่อต้องการใช้ดีกว่า เพราะยังต้องรัน timidity -iA -Os ก่อนถึงจะสั่ง aconnect ได้ .. จะให้มันรันตอนบูตเลยดูจะเป็นการเปลืองทรัพยากรระบบเปล่าๆ อื่นๆยังมีเทคนิคอีกเล็กน้อยสำหรับ TiMidity++ เพื่อให้การทำงานกับมิดี้ตอบสนองได้ดีขึ้นครับ ... ปกติ TiMidity ใช้บัฟเฟอร์ขนาดใหญ่เพื่อให้เพลย์ได้ราบรื่น แต่ก็ทำให้มี latency เยอะซึ่งไม่เหมาะกับโปรแกรมที่ต้องการทำงานแบบเรียลไทม์ เช่น โปรแกรมซีเควนเซอร์ อย่าง Rosegarden หรือ Noteedit ทางแก้คือกำหนดบัฟเฟอร์ให้เล็กลงด้วยออพชัน -B ค่าที่เหมาะๆ มีคนแนะมาว่าใช้ -B2,8 ส่วนตัวผมใช้ -B8,8 กำลังพอดี ถ้า TiMidity++ กินซีพียูเยอะ และต้องการลดมันลง สามารถทำได้โดยยกเลิกเอฟเฟกต์ต่างๆ เช่น reverb และ/หรือ chorus โดยกำหนดออพชัน -EFreverb=0 และ/หรือ -EFchorus=0 ตามลำดับ ถ้ายังไม่พอใจอีก ก็ต้องลองรัน TiMidity++ ด้วย root หรือตั้ง suid root วิธีนี้ทำให้ TiMidity++ สามารถตั้ง scheduling เป็น FIFO ด้วย priority สูงสุดเท่าที่จะทำได้ (ซึ่งมีเฉพาะ root ที่มีสิทธิตั้งค่าแบบนั้น) วิธีนี้ทำให้การตอบสนองดีขึ้นโดยเฉพาะกับโปรแกรมที่ทำงานแบบเรียลไทม์ .. วันนี้ยาวแฮะ มีผู้เยี่ยมชมหน้านี้ 6410 ครั้ง |