ดนตรีทวีตท้าทาย


37

นี้เป็นรุ่นที่เสียงของการเข้ารหัสภาพความท้าทายทวิตเตอร์

ออกแบบรูปแบบการบีบอัดสัญญาณเสียงที่สามารถแสดงเพลงอย่างน้อยหนึ่งนาทีใน 140 ไบต์หรือน้อยกว่าของข้อความที่เข้ารหัส UTF-8 ที่พิมพ์ได้

ใช้งานได้โดยการเขียนโปรแกรมบรรทัดคำสั่งที่ใช้อาร์กิวเมนต์ 3 ตัวต่อไปนี้ (หลังชื่อของโปรแกรมเอง):

  1. สตริงหรือencodedecode
  2. ชื่อไฟล์อินพุต
  3. ชื่อไฟล์ที่ส่งออก

(หากภาษาการเขียนโปรแกรมที่คุณต้องการไม่มีความสามารถในการใช้อาร์กิวเมนต์บรรทัดคำสั่งคุณอาจใช้วิธีอื่น แต่ต้องอธิบายในคำตอบของคุณ)

การencodeดำเนินการจะแปลงจากรูปแบบเสียงที่คุณเลือกเป็นรูปแบบ“ ทวีต” ที่ถูกบีบอัดและการdecodeดำเนินการจะแปลงจากรูปแบบ“ ทวีต” ของคุณไปเป็นรูปแบบเสียงต้นฉบับ (แน่นอนคุณคาดว่าจะใช้การบีบอัดแบบสูญเสียดังนั้นไฟล์เอาต์พุตไม่จำเป็นต้องเหมือนกันกับอินพุตเพียงในรูปแบบเดียวกัน)

รวมไว้ในคำตอบของคุณ:

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

กฎระเบียบ

  • ฉันขอสงวนสิทธิ์ที่จะปิดช่องโหว่ใด ๆ ในกฎการแข่งขันได้ตลอดเวลา
  • [แก้ไขเมื่อวันที่ 24 เมษายน]สำหรับการป้อนข้อมูลencodeฟังก์ชั่นของคุณ(และเอาท์พุทdecodeฟังก์ชั่นของคุณ) คุณสามารถใช้รูปแบบเสียงทั่วไปที่สมเหตุสมผลไม่ว่าจะเป็น:
    • รูปแบบของคลื่นที่ไม่บีบอัดเช่น WAV
    • รูปคลื่นที่บีบอัดเช่น MP3
    • สไตล์“ Sheet music” เช่น MIDI
  • รูปแบบ“ ทวีต” ที่ถูกบีบอัดของคุณจะต้องเข้ารหัสเสียงในไฟล์อินพุต ดังนั้นเอาต์พุตประเภทต่อไปนี้จะไม่ถูกนับ:
    • URI หรือพา ธ ไฟล์ที่ระบุตำแหน่งที่เก็บข้อมูลจริง
    • กุญแจสำคัญในตารางฐานข้อมูลที่เก็บผลลัพธ์จริงเป็น blob
    • สิ่งที่คล้ายกัน
  • โปรแกรมของคุณจะต้องได้รับการออกแบบให้บีบอัดไฟล์เพลงทั่วไปดังนั้นอย่าทำสิ่งที่ผูกติดอยู่กับตัวอย่างเพลงของคุณโดยเฉพาะ ตัวอย่างเช่นหากคุณกำลังแสดง“ Twinkle, Twinkle, Little Star” ชุดคำสั่งการบีบอัดของคุณไม่ควรเขียนโค้ดเฉพาะสำหรับลำดับที่ต้องทำดังกล่าว
  • ผลลัพธ์ของโปรแกรมของคุณควรผ่าน Twitter และไม่ได้รับอันตราย ฉันไม่มีรายการของตัวละครที่แน่นอนที่รองรับ แต่พยายามติดกับตัวอักษรตัวเลขสัญลักษณ์และเครื่องหมายวรรคตอน และหลีกเลี่ยงอักขระควบคุมรวมอักขระเครื่องหมาย BIDI หรือสิ่งแปลก ๆ เช่นนั้น
  • คุณสามารถส่งมากกว่าหนึ่งรายการ

เกณฑ์การตัดสิน

นี่คือการประกวดความนิยม (เช่น net upvotes ส่วนใหญ่ชนะ) แต่ผู้ลงคะแนนจะได้รับการกระตุ้นให้พิจารณาสิ่งต่อไปนี้:

ความถูกต้อง

  • คุณยังจำเพลงหลังจากที่ถูกบีบอัดได้หรือไม่?
  • มันฟังดูดีหรือไม่?
  • คุณยังสามารถรับรู้ถึงการเล่นเครื่องดนตรีชนิดใดได้บ้าง?
  • คุณยังจำเนื้อเพลงได้ไหม? (อาจเป็นไปไม่ได้ แต่มันจะน่าประทับใจถ้าใครทำสำเร็จ)

ความซับซ้อน

การเลือกเพลงตัวอย่างมีความสำคัญที่นี่

  • [เพิ่มวันที่ 24 เมษายน]ความท้าทายนี้จะง่ายที่สุดด้วย MIDI หรือรูปแบบที่คล้ายกัน อย่างไรก็ตามหากคุณใช้ความพยายามอย่างพิเศษเพื่อให้มันทำงานกับฟอร์แมทรูปแบบของ Waveform ได้นั่นก็สมควรที่จะได้รับเครดิตเพิ่ม
  • โครงสร้างคืออะไร แน่นอนว่าคุณสามารถตอบสนองความต้องการในหนึ่งนาทีโดยเพียงแค่ทำซ้ำสี่มาตรการเดียวกันจำนวนครั้งโดยพลการ แต่โครงสร้างเพลงที่ซับซ้อนมากขึ้นสมควรได้รับคะแนนมากขึ้น
  • ฟอร์แมตสามารถจัดการโน้ตจำนวนมากที่เล่นในคราวเดียวได้หรือไม่?

รหัส

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

9
การใช้ MIDI กับ WAV เป็นความท้าทายที่แตกต่างกันอย่างมาก ฉันคิดว่าคุณควร จำกัด รูปแบบเป็น WAV เท่านั้น
grovesNL

10
ฉันกระตือรือร้นที่จะเห็นวิธีแก้ปัญหาใด ๆ แต่ตามจริงแล้ว: บรรจุเสียง 60 วินาทีใน 140 ไบต์หมายความว่าคุณมีน้อยกว่า 19 บิตต่อวินาที มีตัวเข้ารหัสเสียงพูดที่มีประสิทธิภาพสูงเพียงไม่กี่ตัวซึ่งทำงานที่ 300 bps แต่สามารถถอดรหัสเป็นหน่วยเสียงสังเคราะห์โดยมีจุดประสงค์เพื่อสร้างคำพูดที่เข้าใจได้และไม่สามารถเข้ารหัสเพลงได้
jarnbjo

2
คุณกำลังขอซอฟต์แวร์ที่มีปัจจัยการบีบอัดหลายคำสั่งที่มีขนาดใหญ่กว่าสถานะปัจจุบันของศิลปะ หากคุณต้องการคำตอบที่สมเหตุสมผล (เช่นไม่เกี่ยวข้องกับการแต่งเพลงเช่น4'33 "หรืองานศพเดือนมีนาคมเพื่อการสืบเนื่องจากคนหูหนวก ) ฉันขอแนะนำให้คุณลดเวลาลงเหลือ 1 วินาที
squeamish ossifrage

3
@squeamishossifrage เขาไม่ได้บอกว่ามันจะฟังดูเป็นที่รู้จัก
cjfaure

5
มีเป็นข้อโต้แย้งในการสนทนา (และวันรุ่งขึ้น) เกี่ยวกับว่าคุณจริงเฉลี่ย 140 ไบต์หรือทวีตขนาด 140 ตัวอักษร
Peter Taylor

คำตอบ:


26

สกาล่า

แน่นอนว่ามันจะง่ายกว่าในการเข้ารหัสไฟล์ MIDI แต่ใครบ้างที่มีไฟล์ MIDI วางอยู่รอบ ๆ ไม่ใช่ 1997!

สิ่งแรกก่อน: ฉันตัดสินใจที่จะตีความ "Unicode byte" เป็น "Unicode char" และใช้ตัวอักษร CJK เพราะ:

  • มันตรงกับความท้าทายของภาพ
  • Twitter นั้นเท่ห์มาก ๆ
  • ฉันต้องการบิตเหล่านั้นจริงๆ

มีเทคนิคเล็กน้อยที่ฉันใช้ในการบีบเอนโทรปีทุกหยดสุดท้ายจากแหล่งข้อมูล:

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

ต่อไปฉันจำจากชั้นเรียนดนตรีระดับสูงที่การเปลี่ยนโน้ตส่วนใหญ่มีขนาดเล็ก (ขึ้นหรือลงหนึ่งโน้ต) การกระโดดเป็นเรื่องธรรมดาน้อย สิ่งนี้บอกเราว่าอาจมีขนาดเอนโทรปีในการกระโดดน้อยกว่าโน้ตตัวเอง

ดังนั้นวิธีการของเราคือการแบ่งแหล่งข้อมูลของเราออกเป็นหลายช่วงตึก - ฉันพบว่า 14 บล็อกต่อวินาทีทำงานได้ดี (บันทึกด้านข้างฉันมักจะสงสัยว่าทำไมการเข้ารหัสเสียงที่ 44100 Hz ปรากฎว่า 44100 มีปัจจัยมากมาย ดังนั้นฉันสามารถเลือก 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 14, 15, 18, 20, 21, 25, 28 หรือ 30 บล็อคต่อวินาทีและมันจะแบ่งออกอย่างหมดจด ) จากนั้นเราก็บล็อก FFT เหล่านี้ (ก็ไม่ได้เร็วเพราะห้องสมุดที่ฉันใช้นั้นไม่เร็วสำหรับบล็อกที่ไม่ได้ใช้กำลัง 2 และในทางเทคนิคฉันใช้การแปลงฮาร์ทลี่ย์ไม่ใช่ฟูริเยร์)

จากนั้นเราจะพบโน้ตที่ให้เสียงดังที่สุด (ฉันใช้A-weighting ที่มีการตัดสูงและต่ำซึ่งส่วนใหญ่เป็นเพราะใช้งานได้ง่ายที่สุด) และเข้ารหัสโน้ตนี้หรือเข้ารหัสเงียบ คือความเงียบ)

จากนั้นเราแปลโน้ตที่เข้ารหัสของเราไปเป็นกระโดด กระบวนการแปลเป็นข้อความคล้ายกับคำถามการบีบอัดรูปภาพ (แต่เกี่ยวข้องกับการใช้ BigInteger ในทางที่ไม่เหมาะสม)

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

ดังนั้นเรามีเป้าหมาย 140 ตัว เราเริ่มต้นด้วยการเข้ารหัสที่คุณภาพ 1.0 (คุณภาพสูงสุด) และดูว่ามีกี่ตัวอักษร ถ้ามันมากเกินไปเราจะลดลงเหลือ 0.95 และทำซ้ำจนกว่าเราจะมีถึง 140 ตัวอักษร (หรือเรายอมแพ้หลังจากคุณภาพ 0.05) สิ่งนี้ทำให้เอ็นโค้ดเดอร์เป็นเอ็นโค้ดเดอร์ n-pass สำหรับ n <= 20 (แม้ว่าจะไม่มีประสิทธิภาพอย่างมากในพื้นที่อื่นเช่นกันดังนั้น m'eh)

เข้ารหัส / ถอดรหัสคาดว่าเสียงในรูปแบบ s16be ขาวดำ สามารถทำได้โดยใช้ avconv เป็น:

#decoding ogg to s16be, and keeping only the first 60s
avconv -i input.ogg -ac 1 -ar 44100 -f s16be -t 60s input.raw
#encoding s16be to mp3
avconv -f s16be -ac 1 -ar 44100 -i output.raw output.mp3

วิธีรันโปรแกรมเปลี่ยนไฟล์:

sbt "run-main com.stackexchange.codegolf.twelvestring.TwelveString encode input.raw encoded.txt"
sbt "run-main com.stackexchange.codegolf.twelvestring.TwelveString decode encoded.txt output.raw"

รหัสเต็มรูปแบบที่https://github.com/jamespic/twelvestring

ข้อผิดพลาดที่ควรทราบ: คุณจะต้องใช้ไลบรารีการเข้ารหัสทางคณิตศาสตร์ของ nayuki ซึ่งปัจจุบันยังไม่มีสิ่งประดิษฐ์ Maven ให้ใช้งาน แต่คุณจะต้องสร้างทั้งในประเทศและติดตั้งส้อม developster ของมัน

และนี่คือตัวอย่างบางส่วน พวกเขาฟังดูน่ากลัว แต่เป็นที่รู้จักเกี่ยวกับ:

  • เบโธเฟนวันที่ 5: เดิม , การเข้ารหัส -刲檁囉罓佖镱賑皌蝩蔲恁峕逊躹呯兲搆摼蝺筶槛庬一掛獴趤笲銗娵纜喫覤粠僭嫭裵獄鱨蠰儏咍箪浝姑椻趕挍呪白鸞盙宠埘謭擆闯脲誜忘椐笸囃庣稨俖咛脔湙弻籚砌鍖裏橈镙訁鹻塿骱踠筟七趇杅峇敖窈裞瘫峦咰呹櫬茏蛏姆臸胝婁遼憀麁黦掏毈喙眝綄鴀耢椚筤菮蟞斗俼湛营筬禴籙嬧窻丄
  • ขน Elise: เดิม , การเข้ารหัส -訖忢擫鏝拪纒铇鯪薯鉰孝暱埛痏絘僌莻暆鴈屖鳮絒婘譮蠣託騶腀饚緂柤碠瞢碩脅歙棆敗辦冏鄔酾萖苯劺誺軩忇穤锳婁伉巠桭晘酉筟緵俅怚尵鎽蜓崁飿嘔但鈐謽酝屮呤誥俊覊鶮龔癸埙煂臙牎繬肜摲炚雗頨款驦燈菩凧咁楾媡夥俰欓焵韀冊嗥燠鱧駟髉
  • Twinkle Twinkle ดาวเล็ก: เดิม , การเข้ารหัส -欠悺矜莳錥鷗谴裴皽鳺憝漿箔皇殤鸧蜻猻丱
  • สนุก Chiptune: เดิม , การเข้ารหัส -简詐諥尘牿扫鲑龮箫颫齰蠏騁煟靸阒萎囦鮇雝愯訖芉馄鈿鬦嶏觲沠丆贀蛑蛀漥荤侲咔麑桬鲠僵擕灼攲陇亄鹘琾業纟鵼牤棌匩碆踬葫鶙懲欃铳樯柇鋡疡衻澯伅墇搢囻荸香貱夹咽蟽籐屈锂蛉袒貊屨鈦夜镤沄鍡唦魮骬乔蚖醶矕咻喸碋利褼裊匎嶮窢幘六沧鼝瞮坡葍帷锆邵旻符琨鱴郤栱烇仾椃騋荄嘵統篏珆罽

ปรับปรุง

ฉัน tweaked ธรณีประตูเงียบในรหัสและเข้ารหัสอีกครั้ง การเข้ารหัสได้รับการปรับปรุงให้สอดคล้อง นอกจากนี้ฉันเพิ่มเพลงอื่น (ในทางเทคนิคไม่ใช่โอเพ่นซอร์ส แต่ฉันสงสัยว่าเจ้าของลิขสิทธิ์ดั้งเดิมจะรู้สึกว่า IP ของพวกเขากำลังถูกคุกคาม) เพื่อความสนุกสนาน:

  • Imperial March: original , encode - March 讶湠衢焅喋藭嗗唂焰銯艉鶱縩巻痭虊窻熲紆耺哅淙苉嘏庸锺禒旇蘄籷遪刨繱蕖嬯摺祑仰軈牰杊瘷棏郖弘卄浕眮騜阖鏴鶺艂税寛柭菸採偋隆兎豅蚦紛襈洋折踜跅軩树爺奘庄玫亳攩獼匑仡葾昐炡瞱咏斎煟价藭恐鷖璌榍脅樐嬨勀茌愋

ปรับปรุงเพิ่มเติม

ฉันเปลี่ยนเอ็นโค้ดเดอร์นิดหน่อยและมันก็มีผลกระทบต่อคุณภาพอย่างน่าประหลาดใจ (ฉันลืมไปว่าใน DHT สัญญาณออกนอกเฟสนั้นมีผลลบอย่างมีประสิทธิภาพ

โค้ดรุ่นก่อนหน้านี้ใช้สัญญาณนอกเฟสที่ใหญ่กว่า แต่ตอนนี้เราใช้ RMS นอกจากนี้ฉันได้เพิ่มฟังก์ชั่นหน้าต่างที่ค่อนข้างอนุรักษ์นิยมให้กับตัวเข้ารหัส (Tukey, alpha 0.3) เพื่อพยายามต่อสู้กับสิ่งประดิษฐ์

ทุกอย่างอัพเดทตาม


1
ฉันเล่น Twinkle Twinkle และ Chiptune ไม่ได้ Fur Elise ค่อนข้างใกล้ในขณะที่ Beethoven แทบจะไม่เป็นที่รู้จักเลยฮ่าฮ่า
justhalf

คุณต้องการลอง Twinkle Twinkle และ Chiptune อีกครั้งหรือไม่ ฉันคิดว่าฉันได้แก้ไข URL แล้ว
James_pic

1
มันใช้งานได้แล้ว Twinkle Twinkle ค่อนข้างเป็นสายเลือด แต่จะเกิดอะไรขึ้นในที่สุด?
justhalf

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

1
ใช่ในความเป็นจริงมันเป็นอย่างแน่นอน มีBitOutputStream::closeวิธีที่ฉันลืมโทร ฉันจะแก้ไขรหัสและอัปเดตผลลัพธ์
James_pic

11

หลาม

ฉันไม่ได้ทำ mangling พิเศษใด ๆ เกี่ยวกับ UTF-8 ดังนั้นการส่งของฉันจึงผ่านข้อกำหนด 140 ไบต์ ฉันไม่อ้างสิทธิ์ใด ๆ เกี่ยวกับประโยชน์ความถูกต้องหรือประสิทธิภาพของโซลูชันของฉัน

ฉันใช้อัตราตัวอย่าง 44100 Hz สำหรับอินพุตและเอาต์พุต SAMPLES_PER_BYTE ควบคุมคุณภาพของการแปลง ยิ่งจำนวนลดลงเสียงก็จะยิ่งมีคุณภาพดีขึ้น ค่าที่ฉันใช้จะได้รับในส่วนผลลัพธ์

การใช้

เปลี่ยนเป็นรหัส

ไฟล์อินพุตควรเป็น wav มันเข้ารหัสช่องทางแรกเท่านั้น

twusic.py -e [input file] > output.b64

ถอดรหัส

twusic.py -d [input file] > output.raw

เล่นเพลงที่ถอดรหัส

aplay -f U8 --rate=[rate of input file] output.raw

รหัส

#!/usr/bin/env python
SAMPLES_PER_BYTE = 25450

from math import sin, pi, log
from decimal import Decimal

PI_2 = Decimal(2) * Decimal(pi)

FIXED_NOTE = Decimal('220') # A
A = Decimal('2') ** (Decimal('1') / Decimal('12'))
A_LN = A.ln()

def freq(note):
    return FIXED_NOTE * (A ** Decimal(note))

def note(freq):
    return (Decimal(freq) / FIXED_NOTE).ln() / A_LN

VOLUME_MAX = Decimal('8')
def volume(level):
    return Decimal('127') * (Decimal(level+1).ln() / VOLUME_MAX.ln())

def antivolume(level):
    x = Decimal(level) / Decimal('127')
    y = VOLUME_MAX ** x
    return y - 1

NOTES = [freq(step) for step in xrange(-16, 16)]
VOLUMES = [volume(level) for level in xrange(0, VOLUME_MAX)]


def play(stream, data):
    t = 0
    for x in data:
        x = ord(x)
        w = PI_2 * NOTES[(x&0xf8) >> 3] / Decimal(16000)
        a = float(VOLUMES[x&0x07])
        for _ in xrange(0, SAMPLES_PER_BYTE):
            stream.write(chr(int(128+(a*sin(w*t)))))
            t += 1

NOTE_MAP = {'A': 0b00000000,
    'g': 0b00001000,
    'G': 0b00010000,
    'f': 0b00011000,
    'F': 0b00100000,
    'E': 0b00101000,
    'd': 0b00110000,
    'D': 0b00111000,
    'c': 0b01000000,
    'C': 0b01001000,
    'B': 0b01010000,
    'a': 0b01011000}

def convert(notes, volume):
    result = []
    for n in notes:
        if n == ' ':
            result += '\00'
        else:
            result += chr(NOTE_MAP[n] | (volume & 0x07)) * 2
    return ''.join(result)

TWINKLE = convert('C C G G A A GG' +
                    'F F E E D D CC' +
                    'G G F F E E DD' +
                    'G G F F E E DD' +
                    'C C G G A A GG' +
                    'F F E E D D CC', 0x7)

if __name__ == '__main__':
    from base64 import b64encode, b64decode
    import numpy as np
    from numpy.fft import fft, fftfreq
    import wave
    import sys

    if len(sys.argv) != 3:
        print 'must specify -e or -d plus a filename'
        sys.exit(1)

    if sys.argv[1] == '-e':
        w = wave.open(sys.argv[2], 'rb')

        try:
            output = []
            (n_channels, sampwidth, framerate, n_frames, comptype, compname) = w.getparams()
            dtype = '<i' + str(sampwidth)

            # Find max amplitude
            frames = np.abs(np.frombuffer(w.readframes(n_frames), dtype=dtype)[::n_channels])
            max_amp = np.percentile(frames, 85)

            w.rewind()

            read = 0
            while read < n_frames:
                to_read = min(n_frames-read, SAMPLES_PER_BYTE)
                raw_frames = w.readframes(to_read)
                read += to_read

                frames = np.frombuffer(raw_frames, dtype=dtype)[::n_channels]
                absolute = np.abs(frames)
                amp = np.mean(absolute)

                amp = int(round(antivolume(min((amp / max_amp) * 127, 127))))

                result = fft(frames)
                freqs = fftfreq(len(frames))

                while True:
                    idx = np.argmax(np.abs(result)**2)
                    freq = freqs[idx]
                    hz = abs(freq * framerate)
                    if hz > 0:
                        break
                    result = np.delete(result, idx)
                    if len(result) <= 0:
                        hz = 220
                        amp = 0
                        break

                n = int(round(note(hz)))
                n &= 0x1F
                n <<= 3
                n |= amp & 0x07
                output.append(chr(n))
        finally:
            w.close()
        print b64encode(''.join(output)).rstrip('=')
    else:
        with open(sys.argv[2], 'rb') as f:
            data = f.read()
        data = data + '=' * (4-len(data)%4)
        play(sys.stdout, b64decode(data))

ปัจจัยการผลิต

ส่งอย่างเป็นทางการของฉันคือกะทันหันสำหรับเปียโนและ Beatboxโดยเควิน MacLeod สำหรับไฟล์นี้ฉันใช้ SAMPLES_PER_BYTE จาก 25450

ฉันยังใช้เสรีภาพในการเข้ารหัสTwinkle, Twinkle, Little Starด้วย SAMPLES_PER_BYTE 10200 เสียงดีกว่ามาก

ผลลัพธ์

ทันควันสำหรับ Pianoforte และ Beatbox

aWnxQDg4mWqZWVl6W+LyOThfHOPyQThAe4x5XCqJK1EJ8Rh6jXt5XEMpk1Epe5JqTJJDSisrkkNCSqnSkkJDkiorCZHhCxsq8nlakfEp8vNb8iqLysp6MpJ7s4x7XlxdW4qKMinJKho

ลิงค์

Twinkle, Twinkle Little Star

HBobGlJSUlJSY2FlYVNRUVFCQkJCQjs5PDksKisqGxoZGVFTUVNRREFDQjs6OjoqKykpKVRRVFJDQkJCOjs6OzksKikpGxobG1JSUlNRZWFlYVNSUVFCQkJDQTw5PDorKisqGhsZGRk

ลิงค์

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