สร้างเสียงสุ่มเพื่อความสนุกสนานใน / dev / snd /


41

เมื่อเร็ว ๆ นี้ฉันได้สำรวจโฟลเดอร์ enchanted / dev ฉันต้องการเขียนข้อมูลสุ่มไปยังอุปกรณ์เสียงเพื่อสร้างเสียงรบกวน

ฉันใช้ ALSA

ดังนั้นฉันจึงแนะนำให้ cat ทำการไพพ์ข้อมูลสุ่มไปยังไฟล์เล่นในโฟลเดอร์ / dev ...

 cat file-of-random-data > /dev/snd/pcmC0D0p

จากนั้นฉันก็รับสิ่งที่ดูเหมือนว่าจะเป็นข้อผิดพลาดจากแมว

 cat: write error: File descriptor in bad state

ฉันจะแก้ไขสิ่งนี้ได้อย่างไรเพื่อที่ฉันจะได้ฟังการเล่นแบบคงที่ที่อร่อยจากการ์ดเสียงของฉัน


1
ฉันคิดว่าคุณต้องส่งข้อมูล PCMแบบสุ่มหรือบางทีคุณอาจต้องตั้งค่าอุปกรณ์ด้วย ioctls สองสามอันก่อน - คุณไม่สามารถถ่ายโอนข้อมูลแบบสุ่มไบต์ได้
Gilles 'หยุดความชั่วร้าย' ใน

@Gilles ตาม Wikipedia, .wav คือ PCM และฉันได้ผลลัพธ์เหมือนกันทุกประการเมื่อแทนที่ไฟล์แบบสุ่มด้วยไฟล์. wav ฉันจะตรวจสอบการตั้งค่าการควบคุมเข้า / ออกบางอย่าง
โจนส์

ใครบางคนมีตัวชี้สำหรับการสอนเกี่ยวกับวิธีการตั้งค่า ioctls บางอย่าง? สำหรับสิ่งที่เรียกว่า ioctls ฉันคิดว่า ALSA เป็น API ควรมีส่วนต่อประสานสำหรับอินพุตและเอาต์พุต
โจนส์

นี่คือตัวอย่างการทำงานวิธีการเขียนข้อมูล pcm โดยตรงไปยังไฟล์อุปกรณ์: github.com/igor-liferenko/pcm
Igor Liferenko

คำตอบ:


46

ฉันคิดว่าเหตุผลที่สิ่งนี้ไม่ได้ผลสำหรับคุณเนื่องจากอินเทอร์เฟซนั้นเลิกใช้แล้ว ปกติคุณจะไม่สามารถเขียนเสียงโดยใช้/dev/dspอีกต่อไปอย่างน้อยก็โดยไม่ยุ่งยาก

มีโปรแกรมที่จะทำให้สิ่งนี้สำเร็จสำหรับคุณในระบบของคุณ: padsp. นี่จะแม็พ/dev/audioหรือ/dev/dspไฟล์ไปยังระบบเซิร์ฟเวอร์เสียงใหม่

sudo suไฟขึ้นสถานีและได้รับเข้าสู่โหมดรากด้วย

แล้วฉันจะไปcat /dev/urandomและท่อส่งออกลงpadspและใช้คำสั่งที่จะส่งข้อมูลไปยังtee /dev/audioคุณจะได้รับตันของขยะใน terminal /dev/nullของคุณดังนั้นคุณอาจต้องการที่จะเปลี่ยนเส้นทางไปยัง

เมื่อคุณอยู่ใน superuser ลองคำสั่งนี้:

cat /dev/urandom | padsp tee /dev/audio > /dev/null

คุณอาจต้องการลองกับอุปกรณ์อื่น ๆ เช่นเมาส์ของคุณ: การใช้งาน: /dev/psauxตัวอย่างเช่นหรือไดรเวอร์ usb คุณสามารถเรียกใช้หน่วยความจำของคุณผ่านมัน: /dev/mem

หวังว่านี่จะอธิบายได้อย่างชัดเจนว่าทำไมมันไม่ทำงานมาก่อน

โดยส่วนตัวแล้วฉันพบว่าเม้าส์และหน่วยความจำนั้นน่าสนใจกว่าการเล่นสแตติกแบบสุ่ม!


1
ขอบคุณมาก! นี่คือสิ่งที่ฉันกำลังมองหา ตอบเต็ม 7 เดือนหลังจากโพสต์คำถาม! :-)
jones

3
ดูเหมือนว่าsudoไม่จำเป็นต้องมีสิทธิ์พิเศษสำหรับสิ่งนี้
iyrin

2
ขอบคุณมาก ๆ. ฉันพบว่าไบนารีนั้นน่าสนใจอย่างประหลาด สิ่งที่ต้องการ / usr / bin / ls / usr / bin / gnome-terminal / usr / bin / mysql
ดอนสดใส

อืมแปลกที่ 'tee' สามารถทำได้ แต่ 'dd of = / dev / audio' ไม่สามารถทำได้
Jasen

@Jasen dd อาจจะเขียนมากเกินไปในแต่ละครั้ง padsp จำลอง / dev / audio เพื่อเปลี่ยนเส้นทางผ่าน alsa dd ที่ไม่มี padsp จะไม่เห็น / dev / audio เว้นแต่ว่าการจำลองแบบ OSS ในเคอร์เนลถูกเปิดใช้งาน (และโดยค่าเริ่มต้นไม่ใช่) และฉันคิดว่าการเขียนบล็อกขนาดใหญ่ที่ใหญ่กว่าบัฟเฟอร์ในไดรเวอร์อาจล้มเหลวได้
พอลสเตเลียน

8

cat /dev/urandom | aplay เป็นคำสั่งที่ต้องพิมพ์ หากคุณไม่ได้อยู่ในกลุ่ม "เสียง" คุณสามารถนำหน้าเพลย์ด้วย sudo สิ่งนี้ยังไม่รบกวน daemons ใด ๆ (ฉันกำลังทำงานpulseaudioในขณะที่คำสั่งนี้ทำงานและได้ยิน "เสียง"

แก้ไข (6 สิงหาคม 2019): ในรุ่นเก่าของคำสั่งฉันยังมีpadsp teeสิ่งที่ระหว่างและcat aplayตอนนี้ฉันทำงานในทุ่งจริง ๆ แล้วฉันก็รู้ว่ามันไม่สมเหตุสมผลเลย นอกจากนี้ฉันรู้ว่าคำสั่งที่ปรับปรุงแล้ว (คำที่เห็นได้ในตอนต้นของคำตอบนี้) ทำงานได้เพราะฉันใช้มันหลายครั้งต่อวันในที่ทำงาน


6
ฉันใช้ ALSA และไม่จำเป็นต้องใช้ "padsp tee"
Geremia

1
ในประสบการณ์ pulseaudio ของฉัน (และอะไรก็ตามที่ Ubuntu ใช้เมื่อ PA ไม่ทำงาน) ที่padsp teeต้องการ (ฉันมีความแม่นยำ 12.04.2 ในเวลานั้น) สิ่งนี้คือคุณไม่ควรลองถ่ายโอนข้อมูลลงในอุปกรณ์โดยตรงแม้ว่าคุณจะเป็นรูท ( เท่าที่ฉันรู้ว่ามีไฟล์ไม่กี่ไฟล์ที่สามารถอ่านได้และไม่มีใครเขียนได้ในโฟลเดอร์ / dev) เพราะคุณอาจได้รับข้อผิดพลาด (ในกรณีที่ดีที่สุดซึ่งได้รับการพบบ่อยมากขึ้นในการอัพเดทแต่ละครั้ง) ทำให้เคอร์เนลเกิดความผิดพลาด ในบางกรณี ควรใช้องค์ประกอบที่ไม่มีสิทธิพิเศษเช่น aplay เพื่อทำสิ่งนี้ (ต้องใช้กลุ่มเสียงหรือรูท แต่น่าเสียดาย) @geremia
Paul Stelian

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

3

ลอง / dev / audio หรือหนึ่งในอุปกรณ์อื่นภายใต้ / dev / snd ไม่ใช่ว่าทั้งหมดจะเป็นที่เก็บข้อมูลเสียงคุณอาจมีเครื่องผสมไมโครโฟนหรืออะไรบางอย่าง


1
ขอบคุณสำหรับการตอบกลับ. ตาม / proc / asound / devices / dev / snd / pcmC0D0p เป็นอุปกรณ์ที่เหมาะสมสำหรับการเล่นไฟล์เสียง (ดังนั้น 'p')
jones

1
นอกจากนี้ฉันไม่แน่ใจ แต่สามารถมี "ไฟล์" หลายไฟล์สำหรับการเล่นได้หรือไม่ ฉันไม่มี '/ dev / audio' ฉันคิดว่า '/ dev / audio' มีบางอย่างเกี่ยวกับ OSS ซึ่งใช้กับเคอร์เนลรุ่นเก่า (ก่อน 2.5)
jones

2

daemon เสียง (เช่นpulseaudio) ถือล็อคในอุปกรณ์หรือไม่ lsofฉันคิดว่าคุณจะพบว่าหากสิ่งอื่นที่มีการจัดการในทาง


1
ขอบคุณสำหรับคำแนะนำที่เป็นประโยชน์ ผมได้มีการตรวจสอบการใช้และgrep ใช้แต่มันไม่ได้อยู่ใน ฉันได้รับการตรวจสอบอีกครั้งโดยไปที่เพื่อดูว่ามีไฟล์สำหรับล็อคในอุปกรณ์หรือไม่ บอกว่าโฟลเดอร์ว่างเปล่า ดังนั้นฉันเดาว่าไม่มีการล็อก pcmC0D0plsofpulseaudio/dev/snd/controlC0/dev/snd/pcmC0D0p/var/lockls -al
jones

@ โจนส์ถือล็อคในการควบคุมอาจจะเพียงพอที่จะล็อคการ์ดทั้งหมดขึ้นอยู่กับไดรเวอร์ (ขออภัยสำหรับการตอบหลังจาก 8 ปีตอนนี้ฉันเรียนรู้ด้วยตัวเอง)
พอลสเตเลียน

0

TL; DR: พารามิเตอร์ของอุปกรณ์จะต้องตั้งค่าก่อนที่จะอ่านหรือเขียนข้อมูลลงไป

เป็นขั้นเป็นตอน:

  1. เปิดอุปกรณ์ PCM fd = open("/dev/snd/pcmC0D0p", O_RDWR)เช่น: หลังจากเปิด PCM อยู่ในOPENสถานะ

  2. ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, (struct snd_pcm_hw_params*) p)ตั้งค่าพารามิเตอร์ด้วย โครงสร้างพารามิเตอร์ฮาร์ดแวร์มีมาสก์ (แต่ละบิตคือค่า) และช่วงเวลา ( ช่วง [ต่ำสุด, สูงสุด]) พารามิเตอร์ที่ไม่ได้ถูกตั้งค่าจะต้องผ่านการเติม (บิต / ค่าทั้งหมดที่ตั้งค่าสำหรับมาสก์; ช่วงเต็มสำหรับช่วงเวลา) หลังจากตั้งค่าพารามิเตอร์ฮาร์ดแวร์ PCM จะอยู่ในSETUPสถานะ ดูที่pcm_set_config ()ของ TinyALSA เพื่อรับรหัส

    การตั้งค่าACCESS, FORMAT, RATE, CHANNELS, PERIOD_SIZEและPERIODSจะเพียงพอ พารามิเตอร์อื่น ๆ ที่มีสายพันธุ์ของเหล่านี้ยกเว้นว่าในอุปกรณ์บางอย่างอาจจะกำหนดให้หลายที่ไม่ใช่ของBUFFER_SIZEPERIOD_SIZE

  3. โทรioctl(fd, SNDRV_PCM_IOCTL_PREPARE)เพื่อเตรียมอุปกรณ์และตัวแปรรันไทม์ของ ALSA หลังจากนี้ PCM อยู่ในPREPAREDสถานะ

  4. เริ่มอ่าน (จับภาพ) หรือเขียน (เล่น)

แอปพลิเคชั่นที่น้อยที่สุดสำหรับการอ่านหรือเขียนไปยังอุปกรณ์ PCM จะมีรหัสส่วนใหญ่เกี่ยวกับการปรับเปลี่ยนพารามิเตอร์ฮาร์ดแวร์


ฉันไม่แน่ใจว่างานอ่าน / เขียนจริงหรือไม่เนื่องจาก aplay ใช้ (อย่างน้อยในระบบที่ฉันพัฒนา) ioctl (fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, ... ) และไม่ใช่การเขียนที่แท้จริง () บนการเล่น ALSA เองมี wrapper ที่ใช้จุดอ่าน / เขียนและแปลมันไปยัง ioctl หรือไม่?
พอลสเตเลียน

@ PaulStelian ใช่ ดูความหมายของการดำเนินงานไฟล์สำหรับ PCM ในsnd_pcm_read()และsnd_pcm_write(), ไบต์จะถูกแปลงเป็นเฟรม
Ricardo Biehl Pasquali
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.