การเขียนรหัสการรู้จำเสียงของฉันเอง [ปิด]


17

คำอธิบายปัญหา

ฉันต้องการที่จะใช้การจดจำเสียงเป็นส่วนหนึ่งของโครงการฮาร์ดแวร์ซึ่งฉันต้องการที่จะประกอบด้วยตนเองอย่างสมบูรณ์ (ฉันใช้พลังงานต่ำขนาดเล็กอุปกรณ์ความเร็วต่ำเช่น Arduino และ Raspberry Pi, Kinects ฯลฯ ไม่ใช้คอมพิวเตอร์แบบดั้งเดิมด้วย ระบบปฏิบัติการที่เกี่ยวข้องดังนั้นโครงการปิด / ตนเองประกอบด้วย)

การจดจำเสียงสามารถซับซ้อนมากขึ้นอยู่กับระดับของความซับซ้อนที่คุณต้องการ ฉันมีสิ่งที่ฉันเชื่อว่าเป็นข้อกำหนดที่เรียบง่าย ฉันแค่อยากจะจำเสียงของตัวเองและฉันมีพจนานุกรมเล็ก ๆ จำนวน 20 คำขึ้นไปที่ฉันอยากจะจำ ดังนั้นฉันไม่จำเป็นต้องมีห้องสมุดรู้จำเสียงพูดเป็นข้อความและเสียงที่ซับซ้อนหรือซอฟต์แวร์บุคคลที่สามที่ยอดเยี่ยมใด ๆ ที่ฉันค้นหาผ่านเครื่องมือค้นหาทางอินเทอร์เน็ต (ไม่มีปัญหาเหล่านี้!) ฉันเชื่อว่าความต้องการของฉัน "ง่ายพอ" (ภายในเหตุผล) ที่ฉันสามารถเขียนรหัสโซลูชันของตัวเอง ฉันสงสัยว่าถ้าใครเขียนกระบวนการของตัวเองแบบนี้และวิธีการของฉันนั้นมีข้อบกพร่องอย่างมากมายหรือไม่? มีวิธีที่ดีกว่าในการทำเช่นนี้โดยไม่ต้องใช้คณิตศาสตร์ในระดับสูงหรือต้องเขียนอัลกอริทึมที่ซับซ้อนหรือไม่? นั่นคือทางออกที่ฉันได้ลองคิดดูด้านล่าง

คำอธิบายโซลูชัน

ฉันจะเขียนสิ่งนี้ในภาษา C แต่ฉันต้องการที่จะพูดคุยเกี่ยวกับกระบวนการที่ไม่เชื่อเรื่องภาษาโดยเพ่งความสนใจไปที่กระบวนการของตนเอง ถ้าอย่างนั้นเราก็สามารถเพิกเฉยได้

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

2. ไมโครโฟนเชื่อมต่อกับอุปกรณ์ฮาร์ดแวร์ของฉันใช้รหัสของฉัน [1] รหัสกำลังทำการเก็บตัวอย่างความยาวคงที่อย่างต่อเนื่องตัวอย่างความยาว 10 มิลลิวินาทีและเก็บตัวอย่าง 10 ตัวอย่างติดต่อกันในรูปแบบการบันทึกแบบวงกลม [2] (ฉันกำลังประดิษฐ์ตัวเลขเหล่านี้อยู่ด้านบนของหัวของฉันดังนั้นพวกเขาจึงเป็นเพียงตัวอย่างเพื่ออธิบายกระบวนการ)

[1] อาจมีการเชื่อมต่อผ่านตัวกรองแบนด์พาสและ op-amp เช่นเดียวกับการบันทึกพจนานุกรมเพื่อเก็บตัวอย่างเสียงที่จัดเก็บและรวบรวมไว้ให้เล็กลง

[2] ฉันไม่แน่ใจว่าฉันจะเก็บตัวอย่างอย่างไรฉันต้องคิดหาวิธีแม้ว่าฉันจะสร้างตัวเลข (จำนวนเต็ม / ทศนิยม / สองเท่า) ที่แสดงถึงเสียงของตัวอย่าง 10msec (อาจเป็นค่า CRC หรือผลรวม MD5 ของตัวอย่างเสียง) หรือสตรีมของตัวเลข (สตรีมของการอ่านเสียงที่มีความถี่อาจ) ในที่สุด "ตัวอย่าง" จะเป็นตัวเลขหรือตัวเลข ส่วนนี้จะเป็นฮาร์ดแวร์ที่เกี่ยวข้องมากขึ้นดังนั้นจึงไม่ใช่การอภิปรายที่นี่

3. รหัสดูที่มันถูกเก็บไว้ 10 ตัวอย่างติดต่อกันและมองหาการเพิ่มปริมาณเพื่อระบุคำหรือวลีที่ถูกกล่าว (หยุดพักจากความเงียบ) แล้วเพิ่มขึ้นเป็นตัวอย่างการเก็บรวบรวมติดต่อกันเพื่อพูดตัวอย่าง 500 ตัวอย่าง นั่นหมายถึงมันจับเสียง 5 วินาทีในตัวอย่าง 10 มิลลิวินาที

เป็นตัวอย่างหรือ "ชิ้นส่วน" ที่เปรียบเทียบระหว่างเสียงที่เก็บไว้กับเสียงที่ถ่าย หากเปอร์เซ็นต์ตัวอย่างที่จับได้สูงพอจับคู่กับที่เก็บไว้เทียบเท่ารหัสจะถือว่าเป็นคำเดียวกัน

The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also

Stored Sample No           | 1| 2| 3| 4| 5| 6| 7|  8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence

Incoming Sample No         | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value      |  |  |  |20|27|38|46|16|59|77|200|78|

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

สิ่งนี้จะสร้างกลุ่มตัวอย่างดังนี้:

Stored Sample No           | 1| 2| 3| 4| 5| 6|  7| 8|
Stored Sample Value        |27|38|41|16|59|77|200|78|

Incoming Sample No      |-1| 1| 2| 3| 4| 5| 6|  7| 8|
Incoming Sample Value   |20|27|38|46|16|59|81|201|78|

5. ฉันเชื่อว่าการมีค่าเปอร์เซ็นต์สำหรับการปิดแต่ละตัวอย่างต้องเป็นอย่างนั้นดังนั้นตัวอย่าง 7 จึงแตกต่างกันด้วยค่า 1 ซึ่งน้อยกว่า% 1 และค่าเปอร์เซ็นต์สำหรับจำนวนตัวอย่างทั้งหมดซึ่งต้องอยู่ภายในเปอร์เซ็นต์การจับคู่ตัวอย่าง รหัสมีระดับความแม่นยำที่ปรับได้ง่าย

ฉันไม่เคยทำอะไรแบบนี้มาพร้อมกับเสียงมาก่อนมันอาจจะเป็นงานมาก นี่คือเหตุผลที่ฉันถามคำถามนี้ถ้าคุณอาจรู้คำตอบของคำถามนี้ชัดเจนแล้ว (อาจเป็นคำตอบที่เคย) ฉันหวังว่านี่จะไม่เป็นงานที่ใหญ่มากเพราะฮาร์ดแวร์บางอย่างที่ฉันจะใช้งานจะเป็นสิ่งที่ไม่กี่วินาที ในหลายร้อย Megahertz (อาจ 1Ghz โดยใช้ Rasp Pi ที่โอเวอร์คล็อก) ดังนั้นนี่เป็นวิธีที่ค่อนข้างหยาบในการจับคู่ตัวอย่างเสียงโดยใช้กำลังการคำนวณที่ต่ำกว่า ฉันไม่ได้มุ่งหวังผลทันที แต่น้อยกว่า 30 วินาทีเพื่อพิสูจน์แนวคิดที่ดี

PS ฉันไม่มีตัวแทนในการแท็กสิ่งนี้ด้วยแท็กใหม่เช่น "เสียง", "การจดจำเสียง", "เสียง", "การจดจำเสียง" ฯลฯ


17
VR นั้นค่อนข้างซับซ้อนและฉันสงสัยว่าใครบางคนที่ไม่มีความรู้ในสาขานี้จะสามารถพัฒนาไปได้มากโดยไม่ต้องอ่านมากนัก สิ่งแรกที่ทำให้ฉันเกี่ยวกับอัลกอริทึมของคุณคือมันจะไม่จัดการกับความแตกต่างในการพูดคำที่รวดเร็ว แม้แต่ VR ง่ายๆก็ใช้เวลาหลายปีกว่าจะผ่านไปได้
Gort the Robot

4
จริง คุณถ้าคุณไม่คำนึงถึงปีในการพัฒนาอาจต้องการมองเข้าไปในห้องสมุดที่คุณสามารถรวบรวมไปยังเป้าหมายของคุณ ฉันแน่ใจว่าพวกเขามีอยู่จริง
Rig

6
ฉันขอแนะนำขั้นตอนเพิ่มเติม - ทำการแปลงฟูริเยร์ของแต่ละตัวอย่าง สิ่งนี้จะให้ความเข้มของความถี่เสียงแต่ละช่วงเวลามากกว่าที่จะจัดการกับตัวอย่างโดยตรง จะมีความถี่พื้นฐานที่สอดคล้องกันอย่างสมเหตุสมผลสำหรับสระที่คุณพูดปกติซึ่งคุณสามารถตรวจจับได้คุณต้องดูลักษณะเฉพาะของคำพูดไม่ใช่แค่เสียง อย่างที่คนอื่นพูดนี่เป็นงานยาก
Paul Anderson

1
ฉันขอแนะนำให้คุณลองเล่นกับไลบรารี่การจดจำเสียงแม้ว่าคุณจะไม่สามารถใช้มันกับผลิตภัณฑ์ขั้นสุดท้ายได้ พวกเขาจะมีประโยชน์สำหรับการสร้างหลักฐานแนวคิด
SAV

คำตอบ:


3

ฉันไม่เชื่อว่า Arduino มีพลังม้าในการทำเช่นนี้ ทำงานที่ 16Mhz Arduino มีหน่วยความจำประมาณ 32K แม้กระทั่งคำ 20 คำที่สุ่มตัวอย่างใน Mp3 (เล็กกว่านั้น wav) จะไม่พอดีกับมันแม้จะเป็นเพียงเสียงของคุณเอง

rasberi pi อาจใช้กลอุบายการทำงานที่ 700Mhz ขึ้นอยู่กับรุ่นที่อาจมีหน่วยความจำ 512MB ที่ยังไม่ได้แป้งมาก

คุณอาจต้องการฟูริเยร์ ( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )

หรือถ้าคุณตั้งใจจะใช้วอลลุ่มให้ทำค่าเฉลี่ยสองสามตัวอย่างก่อนหน้านี้เช่น
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 // นั่นอาจง่ายมาก ต้องการมาก

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

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


1
  1. Arduino และ Raspberry Pi เป็นบอร์ดต้นแบบที่มีชิปเพียงเล็กน้อย คุณควรมุ่งเน้นไปที่ชิปแรก มองหาบางอย่างด้วยกล่องเครื่องมือ DSP (การประมวลผลสัญญาณดิจิตอล) บางทีคุณอาจมีกล่องเครื่องมือ DSP อยู่แล้วและไม่รู้ตัว กล่องเครื่องมือ DSP มีอัลกอริทึมในการโทรเช่น fft (การแปลงฟูริเยร์เร็ว) และ ifft (inverse fft) สำหรับการวิเคราะห์โดเมนความถี่ที่รวดเร็ว

  2. เน้นสไตล์การเขียนโปรแกรมของคุณ: ตัวอย่างของคุณอยู่ในสแต็กหรือคิวหรือไม่? คุณจะต้องการคิวสำหรับข้อมูลประเภทนี้ คิวดูเหมือนว่า:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |5|7|9|1|2|2|9|8|
    

    การทำซ้ำครั้งถัดไป:

    Position NO --|1|2|3|4|5|6|7|8|
    Sample Value  |0|5|7|9|1|2|2|9|
    ->  First in First out (FIFO)
    

    สังเกตว่าสิ่งต่าง ๆ เปลี่ยนไปทาง 'ถูกต้อง' อย่างไร ฉันคิดว่าคุณอธิบายอัลกอริทึม "แบบวงกลม" เพียงแค่เขียนทับตัวอย่างที่เก่าที่สุดด้วยตัวอย่างที่เก่าที่สุดที่สองจากนั้นเขียนทับตัวอย่างที่เก่าที่สุดที่สองด้วยที่เก่าแก่ที่สุดที่สาม ... จนถึงจุดเริ่มต้นของคิวที่คุณแทรกข้อมูลล่าสุดของคุณ

  3. "โค้ดกำลังทำการสุ่มตัวอย่างความยาวคงที่อย่างต่อเนื่องพูด 10msec" <- ไม่ถูกต้อง คิดแบบนี้: โค้ดทำการสุ่มปริมาณ (ความสูง) ตัวอย่างโดยมีอัตราการสุ่มตัวอย่างที่ 10,000 ตัวอย่างต่อวินาทีซึ่งทำให้แต่ละตัวอย่าง 0.1 มิลลิวินาที

    ความถี่การสุ่มตัวอย่างของคุณคืออะไร? อัตราบิตของปริมาณของคุณคืออะไร? ตัวเลขที่ต่ำกว่าจะช่วยให้คุณเพิ่มหน่วยความจำ ฉันขอแนะนำให้อัตราการสุ่มตัวอย่างต่ำเช่น 6600 ตัวอย่างต่อวินาที (Nyquist) ฉันสงสัยว่า 4 บิต (16 ระดับ) น่าจะเพียงพอสำหรับการจดจำ นั่นคือ 3300 ไบต์ของการบันทึกต่อวินาที ตอนนี้ทำ fft และลบทุกอย่างที่อยู่เหนือ 3300 Hz (ตัวกรองโทรศัพท์) ตอนนี้คุณมี 1,650 ไบต์ใช้สำหรับหนึ่งวินาทีของเสียง เทคนิค DSP เหล่านี้จะช่วยประหยัดหน่วยความจำได้มาก

    ฉันไม่รู้ว่าใครคิดว่า 512 MB นั้นเล็ก ด้วยข้อมูลข้างต้นที่บันทึกได้ 300,000+ วินาที ... มากกว่า 3 วัน

  4. ฉันคิดว่าคุณจะพบโดเมนความถี่ (โดยใช้ fft) เพื่อให้มีสภาพแวดล้อมที่ดีขึ้นในการจดจำเสียง

ฉันหวังว่าฉันจะไม่ทำให้คุณงงเลย :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.