tag:blogger.com,1999:blog-27003790264458326302024-03-19T05:10:35.843+07:00bagustris@/homemove dynamicallybagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comBlogger698125tag:blogger.com,1999:blog-2700379026445832630.post-7463813168508269112024-03-14T14:23:00.009+07:002024-03-18T04:17:03.499+07:00Siapa Pencipta Tuhan?<p>Dalam filosofi, permasalahan siapa pencipta Tuhan (<a href="https://en.wikipedia.org/wiki/Problem_of_the_creator_of_God" target="_blank">problem of the creator of God</a>) adalah topik perdebatan yang tiada habisnya. Argumennya adalah: "Jika alam semesta diciptakan oleh Tuhan, maka siapa pencipta Tuhan?"</p><p>Saya ingin menjawab pertanyaan itu dengan sederhana. Begini analoginya.</p><p>Jika alam semesta, sebagai ciptaan, diibaratkan oleh angka 2, maka sebelum angka dua itu pastilah ada angka sebelumnya, yaitu 1. Angka 2 adalah alam semesta dan angka 1 adalah Tuhan. Lalu, siapa/apa sebelum 1? Tidak ada alias nol, 0. Begitu juga dengan Tuhan, tidak ada penciptanya. </p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-33836119008678382482024-03-07T13:52:00.002+07:002024-03-07T13:52:21.189+07:00Membuat Alias untuk Github Copilot CLIUntuk membuat alias untuk Github Copilot, misal ?? untuk menggantikan `gh copilot suggest`, beberapa baris alias berikut dapat ditambahkan pada fail `.bashrc`.
<pre>alias '??'='gh copilot suggest -t shell'
alias 'git?'='gh copilot suggest -t git'
alias 'explain'='gh copilot explain'
</pre>
Dengan cara ini kita bisa mempermudah hidup dan menghemat waktu. Berikut contohnya:
<pre class="prettyprint lang-bash">bagus@m049:~$ ?? list WAV files less than 1 MB
Welcome to GitHub Copilot in the CLI!
version 0.5.4-beta (2024-01-04)
I'm powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve. For more information, see https://gh.io/gh-copilot-transparency
Suggestion:
find . -name "*.wav" -size -1M
? Select an option
> Exit
bagus@m049:~$ git? show history
Welcome to GitHub Copilot in the CLI!
version 0.5.4-beta (2024-01-04)
I'm powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve. For more information, see https://gh.io/gh-copilot-transparency
Suggestion:
git log
? Select an option
> Exit
bagus@m049:~$ explain "make -j 5"
Welcome to GitHub Copilot in the CLI!
version 0.5.4-beta (2024-01-04)
I'm powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve. For more information, see https://gh.io/gh-copilot-transparency
Explanation:
• make is a build automation tool used to compile and build projects.
• -j 5 specifies the maximum number of jobs (parallel tasks) that make can
run simultaneously. In this case, it is set to 5.
</pre>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-88852174306582236892024-03-06T08:39:00.004+07:002024-03-07T09:20:11.787+07:00Menggunakan (Mini) Conda Untuk Komersial (Institusi Riset, dll)<p>Per 30 September 2020, <a href="https://legal.anaconda.com/policies/en/?name=terms-of-service#terms-of-service" target="_blank">term of service Anaconda berubah</a>; lisensi berbayar dibutuhkan untuk menggunakan Anaconda untuk keperluan komersial (gratis untuk skala kecil, perusahaan kurang 200 orang pekerja). Miniconda dapat digunakan secara gratis, namun setting default dapat menyebabkan akses ke repository berbayarnya (meskipun gratis).</p><p></p><p>Solusi singkatnya adalah menambahkan `conda-forge` pada channel di `.condarc` untuk menggantikan konfigurasi default. Cek dengan `conda config --show channels` sebelum dan sesudah mengganti channel default (tidak tertulis di `.condarc`) dengan `conda-forge`.</p>
<p> Cek setting default channel:</p>
<pre>$ conda config --show channels
channels:
- defaults
</pre>
<p> Ganti channel default dengan menambahkan conda-forge di fail `.condarc` (default di direktori home)</p>
<pre> auto_activate_base: false
channels:
- conda-forge
</pre>
<p> Cek kembali config conda:</p>
<pre>$ conda config --show channels
channels:
- conda-forge
</pre>
Dengan cara ini, Miniconda dapat digunakan secara sah dan halal. Saya menggunakan Miniconda (daripada Anaconda) hanya untuk membuat virtual environment dengan versi python yang berbeda (misal dengan python3.8, python3.12, dll). Instalasi paket dalam python (seperti Numpy, Pandas) tetap saya lakukan dengan pip, bukan dengan Conda.bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-4211433301653520752024-01-31T15:13:00.002+07:002024-03-06T08:40:50.500+07:00Laporan Bulanan Januari 2024<p>Pada bulan ini, saya melakukan dua kali kerja jarak jauh setengah hari dan tiga kali kerja jarak jauh sepanjang hari. Isi dari pekerjaan jarak jauh ini entah menulis laporan (makalah penelitian) untuk pengembangan sistem pengenalan emosi ucapan waktu nyata atau melihat sistem e-learning di kantor (Kursus Pelatihan Dasar untuk Karyawan Asing). Saya terus membangun adapter WavLM untuk sistem pengenalan emosi ucapan Jepang, tetapi hasilnya belum diperoleh. Saya juga meninjau beberapa pengenalan emosi ucapan dan ekspresi vokal termasuk dataset dari Vietnam (dari Konferensi APSIPA 2023), Korpus Ucapan Emosional Anak Rusia (EmoChildRu), vokalisasi nonverbal Jepang (JNV), dan Ucapan Emosional Jepang dengan Konten Verbal dan Ekspresi Nonverbal (JVNV). Saya juga sedang menyiapkan tanggapan untuk sebuah makalah yang diajukan ke <a href="https://lrec-coling-2024.org/" target="_blank">LREC/Coling 2024</a>. Dalam diskusi tertulis, saya menjelaskan daya saing model pra-pelatihan dengan HuBERT Large yang mencapai hasil terbaik di antara model-model pra-pelatihan lainnya, dan juga kesulitan dengan model-model pra-pelatihan lain seperti UniSpeech-SAT dan XLSR-2B. Kesulitan pertama disebabkan oleh desain UniSpeech-SAT yang ditujukan untuk verifikasi pembicara dengan informasi terpisah di antara pembicara, sementara kesulitan kedua disebabkan oleh batasan memori GPU (saat ini saya melatih model saya dengan RTX3090 24 GB VRAM). Komputasi sebelumnya menggunakan model besar seperti XLSR 2B tidak dapat dilakukan karena masalah out-of-memory. Meskipun masalah ini dapat diatasi dengan meningkatkan memori (misalnya, dengan mengupgrade GPU ke A6000 dengan 48 GB VRAM), model yang dihasilkan akan besar ukurannya, yang dapat memperpanjang waktu pemuatan model untuk inferensi. Selain itu, saya juga melakukan pekerjaan administratif menyiapkan dokumen untuk perpanjangan visa.</p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-63046553368696864242023-12-29T09:01:00.007+07:002024-02-26T08:02:48.633+07:00Mencoba Obsidian: note-taking app yang super powerful<p>Dulu saya pernah bertanya-tanya, adakah platform atau aplikasi note-taking yang sederhana, aplikasi tersebut hanya bersifat aplikasi (seperti word processor) namun filenya disimpan dalam file teks sederhana seperti text (TXT) dan markdown (MD)? Bukan menyatu dengan aplikasi seperti Google Keep atau Evernote (bukan app-over-file tapi <a href="https://stephango.com/file-over-app" target="_blank">file-over-app</a>). Ternyata ada, dan saya pernah mencobanya. Dulu saya saya tidak melanjutkan mencobanya karena apa yang saya cari tersebut tidak ketemu, ternyata memang ada. Ketidaktahuan saya memblokade penggunaan aplikasi tersebut waktu itu. Aplikasi itu adalah Obsidian.</p><p>Setelah menggunakan evernote, kemudian pindah ke Google Keep, dan Simplenote, ada beberapa perubahan mendasar yang saya alami. Versi free dari evernote memiliki kemampuan terbatas. Google Keep kemudian mematikan versi luring (offline) sehingga saya tidak bisa melihat catatan saya lewat PC ketika tidak bisa konek internet. Simplenote menjadi second brain bagi saya, namun, ketika catatan saya bertambah banyak dan saya menginginkan catatan terstruktur (linked-notes, notes in note), simplenote menjadi terbatas. Saya pernah mencoba Obsidian sekitar beberapa tahun yang lalu, namun apa yang saya cari (sync dan structured notes) tidak saya temukan karena ketidaktahuan saya.</p><p> </p><p>Organisasi Obsidian (vaults)<br /></p><p>1. Diary -- untuk catatan harian</p><p>2. Fiksi -- untuk mencatat kisah fiksi, seperti draft <a href="https://kbm.id/book/detail/9a239d5e-fd6d-4a80-a89f-26cbe622916d" target="_blank">cerpen</a> atau novel</p><p>3. Non-fiksi -- untuk catatan non-fiksi</p><p>4. Google keep -- archive dari Google Keep yang saya export ke Obsidian</p><p>5. Pengajian -- catatan pengajian dll., ada plugin Quran juga.</p><p><br /></p><p>Demikian, Obsidian telah menjadi otak keempat saya setelah simplenote dan <a href="http://bagustris.blogspot.com/2023/12/blog-baru-di-listed.html" target="_blank">Standard Notes</a>.</p><p><br /></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk0L1R_GzyZIyRnXcRnb8w4ggrgsXY8Sq6X215Zd3TB0WsMXHShHkmrc5chVeOuLhPYW-z4q0Esrr7RhUWt2Klig8PCHc5b7E99NYuqrqz1TzK5juUtpHgXEZFR3KqNs-r1lIvjIe1ucmtxi0rdqwT5LhQdfsRaAydj665L04WlONHHYZ5rBK-XHgScA4/s1366/Screenshot%20from%202023-12-29%2010-59-04.png" style="margin-left: auto; margin-right: auto;"><img alt="Obsidian di Ubuntu 20.04" border="0" data-original-height="768" data-original-width="1366" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk0L1R_GzyZIyRnXcRnb8w4ggrgsXY8Sq6X215Zd3TB0WsMXHShHkmrc5chVeOuLhPYW-z4q0Esrr7RhUWt2Klig8PCHc5b7E99NYuqrqz1TzK5juUtpHgXEZFR3KqNs-r1lIvjIe1ucmtxi0rdqwT5LhQdfsRaAydj665L04WlONHHYZ5rBK-XHgScA4/w640-h360/Screenshot%20from%202023-12-29%2010-59-04.png" title="Obsidian di Ubuntu 20.04" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Obsidian di Ubuntu 20.04<br /></td></tr></tbody></table><br /><p><br /></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-50917819073987597432023-12-28T12:45:00.006+07:002024-01-09T11:39:49.551+07:00Blog baru di Listed<p> Akhirnya, ada platform offline dan online dalam satu portal. Dan platform itu ternyata sudah ada sejak lama. Namanya Standard Notes. Bisa diinstal via snap dengan perintah berikut di Ubuntu.<br /><br />
</p><pre>sudo snap install standard-notes
</pre><p>
Saya suka menulis blog, baik itu di <a href="https://bagustris.blogspot.com"> blogger</a>, <a href="https://bagustris.wordpress.com"> wordpress</a>, <a href="http://medium.com/@btatmaja" target="_blank">medium</a>, atau <a href="https://bagustris.tumblr.com"> tumblr</a>. Masalahnya, sejauh pengetahuan saya saat itu, belum ada platform digital yang bisa berlaku baik untuk offline dan online. Misalnya, saat saya punya ide, saya menuliskannya di editor, word processor, atau note taking app. Kemudian saat saya ingin mempublikasikannya, saya salin tulisan offline tadi ke platform blog yang bersangkutan, misalnya Blogger. Sampai saya menemukan platform/aplikasi Standard Notes yang menyatu dengan <a href="http://listed.to">listed.to</a>.</p><p>Blog baru saya di Listed beralamat di <a href="https://listed.to/@bagus">https://listed.to/@bagus</a>.<br /><br />Dengan platfom ini saya bisa menulis blog on-the-go secara luring, kemudian mempublikasikannya dari perangkat tersebut tanpa harus menyalin dan menempelnya ke internet. Cukup sekali-dua kali klik. Bagi anda yang belum tahu caranya, berikut cara publikasi blog lewat Standard Notes and Listed (<a href="http://www.listed.to">www.listed.to</a>).<br /><br />1. Buka Stantard Notes app atau web app<br />2. Klik ikon Preferences in sisi kanan bawah<br />3. Buka seksi Listed<br />4. Pilih Create New Author<br /><br />Untuk publikasi dari Standard Notes ke Listed (lihat gambar di bawah).<br />1. Klik kanan judul note yang akan dipublish<br />2. Pilih "Listed action" kemudian pilih "Publih to Blog"<br /><br />Voilla, sekarang catatan datam Standard Notes tersebut telah terpublish dalam <a href="http://Listed.to">Listed.to</a>. <br /><br />Karena kemudahan itu, besar kemungkinan saya akan mengeblog di Listed. Blog di blogspot ini mungkin akan dormant, wallahua'lam. Saya belum tahu pastinya, mungkin topik-topik professional akan saya taruh disini, catatan harian di Listed, dan quotes di Tumblr.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC2wXvzXSHBqPpfF-0MyhRjk43Yg5cwTTf1mGi62azo8XXyFuNkcNUNF_kTfAb09kfn71J18kqJ7oIp4gp6x_8cBjLBybF5iIF-kVP31rwfndp7Tg4Ty1U9bBbAgX-pBAh3yBJ5LeGp8qu7LUmWlIOPmCEjNzTdZ2TU-tAcPohSBNEp9mI1LY1hsyHWlM/s2204/standard_notes_publish_to_listed.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1620" data-original-width="2204" height="470" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC2wXvzXSHBqPpfF-0MyhRjk43Yg5cwTTf1mGi62azo8XXyFuNkcNUNF_kTfAb09kfn71J18kqJ7oIp4gp6x_8cBjLBybF5iIF-kVP31rwfndp7Tg4Ty1U9bBbAgX-pBAh3yBJ5LeGp8qu7LUmWlIOPmCEjNzTdZ2TU-tAcPohSBNEp9mI1LY1hsyHWlM/w640-h470/standard_notes_publish_to_listed.png" width="640" /></a></div><p></p><p>Dengan demikian, Standard Noted menjadi otak ketiga saya setelah <a href="https://simplenote.com" target="_blank">simplenote</a>.<br /></p><p></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-50570736847066236282023-12-22T19:59:00.012+07:002024-02-23T12:44:07.284+07:00Tentang Gift dan Ghost Authorship<blockquote><p><span><i>If research misconduct occurs, including guest/gift authorship, the integrity of a researchers is questionable; this can PERMANENTLY and NEGATIVELY affect their career.</i></span></p></blockquote><p> </p><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqTehud_ZjUgsCr8DMYMRgQHByRZ8-lYO9AefK8VQKr4BT9Yn-ZRg_DUd2qSiinjdeuVXBJ8kFlBp4s60DjSTWndUSb3wEL99_SzU-E4tHgxHK0jNH_mk90o-Es3pkchcdHmI4CZOFzecuL_Z244kbGPxLV5yuf0ZTbIhiq3VVg3X7BvFdn6D6ztUo1TE/s771/ghost_authorship.png"><img alt="ghost authorsip" border="0" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqTehud_ZjUgsCr8DMYMRgQHByRZ8-lYO9AefK8VQKr4BT9Yn-ZRg_DUd2qSiinjdeuVXBJ8kFlBp4s60DjSTWndUSb3wEL99_SzU-E4tHgxHK0jNH_mk90o-Es3pkchcdHmI4CZOFzecuL_Z244kbGPxLV5yuf0ZTbIhiq3VVg3X7BvFdn6D6ztUo1TE/w400-h233/ghost_authorship.png" width="400" /></a></div><br /><p></p><p>Salah salah praktek tercela di bidang akademik adalah ghost dan gift authorship, menuliskan nama mereka yang tidak berkontribusi di dalam penulisan paper. Penerbit seperti Elsevier dan Springer memiliki peraturan ketat dalam kasus ini, sekali praktek ini ditemukan, karya yang bersangkutan bisa ditarik. Saya sendiri sudah beberapa kali melaporkan kasus ini, tak peduli rekan sejawat, atasan, atau orang lain. Ada kalanya, mungkin, anda "dipaksa" menuliskan nama teman anda, baik kenalan, teman se-lab, se-kampus, atau se-jurusan. Untuk dimasukkan menjadi penulis (authors), setidaknya ada tiga syarat [1]:<br />1. Kontribusi subtansial dalam riset<br />2. Ikut menulis draft<br />3. Menyetujui versi final dari draft<br /><br />Cara mengetes ghost author, menurut elsevier, adalah bahwa semua penulis mempunyai kemampuan dan kewajiban yang sama dalam mempertahankan ide di dalam tulisannya. Oleh karena itu, jika ada seorang penulis (co-authors) yang tidak bisa menjelaskan atau menjawab pertanyaan terkait tulisannya, bisa jadi penulis itu adalah ghost, guest atau gift author.<br /><br /></p><h4>Compliance is more than just obeying laws.</h4>Dalam publikasi ilmiah, kita memiliki code of conduct. Dalam setiap submisi artikel, kita diwajibkan menuliskan kontribusi setiap penulis dalam artikel. Secara <i>common sense</i>, setiap mereka yang namanya ada pada paper pasti berkontribusi. Hukum penulisan ini wajib kita patuhi. Bahkan diatasnya, ada etika yang seharusnya kita taati juga: menghindari research misconduct termasuk gift, ghost atau honorary authorship ini.<br /><p></p><p></p><p>Jika ada orang lain yang meminta namanya ditulis dalam sebuah paper, sebaliknya ada juga orang yang melarang namanya ditulis dalam sebuah paper. Seorang teman S3 pernah bercerita bahwa professornya, meminta namanya tidak dimasukkan dalam publikasi teman saya tersebut karena dia tidak berkontribusi sama sekali.<br /></p><p><br />Institusi kita punya visi dan misi mulia yang ingin diraih. Kita tidak bisa menghalalkan segala cara untuk meraih visi dan misi itu.<b><i> You CANNOT choose just any method to achieve your goal. There is a "path we should take" among them</i></b>. Goal adalah visi institusi kita yang ingin kita capai. Jelas disini bahwa ghost dan gift authorship tidak termasuk dalam "path we should take".<br /> <br />Rezeki tidak hanya dari insentif publikasi. Masih banyak jalan dan pintu rezeki berkah dan halal lainnya daripada memasukkan nama istri, teman, atau atasan yang tidak berkontribusi pada publikasi ilmiah kita. Praktek tercela ini membahayakan insitusi kita. Semoga kita terhindar dari praktek tercela ini.</p><h4 style="text-align: left;">Ghost authorship untuk memperbesar peluang diterimanya paper</h4><p>Ada kasus dimana peneliti yang sudah meninggal tetap dilibatkan dalam pembuatan paper. Kasus ini [2], ditengarai untuk memperbesar kans diterimanya paper tersebut di sebuah jurnal. Anggaplah peneliti yg sudah meninggal tsb adalah peniliti terkenal, misal peraih nobel. Dengan memasukkan namanya sebagai coauthor maka kans diterimanya sebuah paper dalam jurnal <b>mungkin</b> akan bertambah besar. Hal yang tidak mungkin dilakukan oleh peneliti yang sudah meninggal adalah pada persyaratan nomor 3 authorship di atas: menyetujui versi final. Pun demikian, hal ini (memasukkan penulis yang sudah meninggal) bisa saja dilakukan bila penulis yang telah meninggal tersebut benar-benar berkontribusi dan disebutkan dalam "Aknowledgement" bahwa salah satu penulis telah meninggal sebelum paper diterbitkan.</p><h4>Kenapa ada praktek Ghost Authorship, khususnya di negeri kita?</h4><p>Seorang sejawat bertanya, kenapa kondisi ideal (tidak ada ghost authorship) tidak bisa diterapkan di, khususnya, negeri kita tercinta. Banyak faktor. Diantara banyak fa menurut saya yang paling penting adalah mental peneliti dan kecukupan ekonominya. Di negeri kita, mental peneliti belum terbentuk secara ideal. Alih-alih melakukan "impactful research"; yang dilakukan peneliti adalah bagaimana mendapatkan cuan dari penelitian, entah itu dari insentif, kenaikan pangkat, dll. Disini mental peneliti yang bersangkutan bermasalah. Bisa jadi karena tidak ada pendidikan "Compliance and Researcher Ethics" untuk para peneliti (di institusi saya, setiap peneliti diwajibkan mengambil e-learning ini setiap tahunnya dan wajib lulus ujian e-learning tsb). Kondisi ini diperparah dengan kecukupan ekonomi peneliti yang bersangkutan. Selama kebutuhan dasar belum terpenuhi (sandang, pangan, papan), maka dia akan mencari segala cara (dan mungkin saja menghalalkan segala cara) untuk memenuhi kebutuhan tersebut. Salah satunya dengan meminta rekannya untuk memasukkan namanya saat publikasi. Agar, ketika mendapat insentif, dia juga ikut kecipratan. Sekaligus mempercepat proses kenaikan pangkat.<br /></p><p><br /></p><p>Referensi: </p><p>[1] https://www.jscpt.jp/eng/journal/kitei.html</p><p>[2] https://retractionwatch.com/2024/02/16/highly-cited-scientist-published-dozens-of-papers-after-his-death/</p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-18041148217200528972023-10-27T14:28:00.006+07:002024-03-15T13:31:11.429+07:00Kapan mendengarkan apa kata orang (dan kapan tidak)<p>tl;dr: Kadang kita seharusnya mendengarkan kata orang, kadang kita seharusnya tidak mendengarkan kata orang</p><h4 style="text-align: left;">Kapan seharusnya tidak mendengarkan kata orang</h4><p>Ada dua kisah diantara banyak kisah. Kisahnya Abu Thalib dan seorang yang menaiki keledainya bersama ayahnya. Abu Thalib ingin mengikuti agama nabi Muhammad diakhir hayatnya namun tidak jadi karena mendengarkan apa kata orang. </p><p>Menjelang wafatnya, Nabi mengajak kembali pamannya Abu Thalib untuk bersyahadat, namun Abu Thalib menjawab, "Seandainya kaum Quraisy tidak mencelaku dengan berkata, 'Tidak ada yang mendorongnya mengucapkannya kecuali karena kesedihannya menghadapi maut,' niscaya aku mengucapkannya untukmu." </p><p>Dari sini terlihat bahwa Abu Thalib lebih memilih apa kata orang daripada mengikuti ajakan nabi Muhammad. Abu Thalib tidak ingin dianggap oleh kaum Quraisy bahwa dirinya takut menghadapi kematian sehingga mengubah agamanya.</p><p>Cerita kedua adalah kisah masyhur tentang anak, bapak, dan keledai mereka. Suatu hari ada anak dan bapak yang akan melakukan perjalanan. Mereka adalah 2 orang yang tanggung. Si anak belum dewasa, ia masih remaja yang beranjak. Sedangkan si bapak adalah seorang yang sudah tidak muda lagi, namun belum terlalu tua. Mereka melakukan perjalanan menuju pasar menggunakan keledai tua, namun tubuhnya masih kuat. Hanya saja memang tubuh keledai umumnya berukuran kecil. </p><p>Berangkatlah mereka. Si bapak menunggangi kuda, sedangkan anaknya jalan kaki. Di kampung pertama, mereka disoraki oleh wanita. "Kok, kamu yang naik, sedangkan anakmu yang kecil itu kelelahan berjalan dibelakang?" </p><p>Mendengar itu si Bapak pun turun dari keledai dan menyuruh anaknya untuk naik keledai. Kemudian tak berapa lama, mereka melewati segerombolan orang tua sedang duduk dibawah pohon. Mereka berkata "Mengapa kamu berjalan kaki, kamu kan sudah tua, sedangkan anakmu yang masih muda. Harusnya anakmulah yang jalan, dan engkaulah yang menunggangi kuda? Si anak pun kemudian turun.</p><p>Kemudian di desa lain mereka pun mendapat komentar lagi dari seorang pria berbadan tegap yang terluhat gagah. "Kok cuma satu orang yang naik keledai, kenapa enggak berdua ?". Mendengar itu merekapun menaiki keledai itu bersama-sama. Dua orang naik seekor keledai.</p><p>Mereka melintai kampung berikutnya. Tetapi, ditengah perjalanan, mereka melewati sekelompok orang pecinta binatang. Melihat pemandangan itu, para pecinta binatang ini berkomentar "Kasihanilah binatang yang kurus kering itu. Kalian berdua menungganginya, padahal kalian lebih berat dari pada keledai ini."</p><p>Mendengar itu, bapak dan anak ini lantas turun dari keledai. "Kalau begitu, mari kita berjalan bersama-sama dan kita biarkan keledai ini berjalan di hadapan kita." Kata si Bapak.</p><p>Tak habis sampai disitu mereka masih mendapat komentar lagi. Mereka bertemu orang yang sedang mabuk dan berkata. "Yang pantas itu keledai yang menaiki kalian berdua, sehingga kalian dapat membuatnya terhindar dari kendala-kendala di jalan". Sang bapak yang terpengaruh omongan pun lansgung mengendong si keledai.</p><p>Namun di depan, mereka lagi lagi ditertawakan oleh orang-orang asbab pemandangan aneh itu. Kemudian si bapak berhenti dan menoleh kepada anaknya sambil berkata, "Wahai anakku, jika mendengar dan mengikuti semua omongan manusia. Tidak akan ada habis - habisnya." Dan mereka berdua pun tertawa. [1]</p><p>Dari kisah ini kita mendapat pelajaran bahwa tidak perlu mendengarkan kata orang, selama apa yang kita lakukan itu baik.</p><h4 style="text-align: left;">Kapan seharusnya mendengarkan apa kata orang</h4><p>Ada dua kisah juga. Kisah pertama saat sahabat menawarkan untuk membunuh munafiq di Madinah dan Nabi tidak mengiyakannya karena takut apa kata orang. Kedua, kisah saat nabi berjalan berdua bersama istrinya di malam hari dan sahabat menghindar.</p><p>Kisah pertama adalah seperti ini.</p><p>Setelah Rasulullah selesai menghadapi perang dengan Banu Mustaliq, ada dua orang dari kalangan Muslimin yang bertengkar memperebutkan mata air; yang seorang dari kalangan Muhajirin dan yang seorang lagi dari Anshar. Mereka yang dari Muhajirin berteriak: “Saudara-saudara Muhajirin!” Dibalas oleh Anshar: “Saudara-saudara Anshar!” Pada waktu itulah Abdullah bin Ubay bin Salul, pemimpin kaum munafik di Madinah berkata kepada orang-orang di sekitarnya: "Di kota kita ini sudah banyak kaum Muhajirin. Penggabungan kita dengan mereka akan seperti kata peribahasa: 'Seperti membesarkan anak harimau.' Sungguh, kalau kita sudah kembali ke Madinah, orang yang berkuasa akan mengusir orang yang lebih hina." </p><p>Muhammad Husain Haekal dalam "Umar bin Khattab" menceritakan bahwa kata-kata Abdullah bin Ubai itu oleh sahabat disampaikan kepada Rasulullah, yang ketika itu ada Sayidina Umar bin Khattab . Umar naik pitam mendengar laporan itu dan katanya: “Rasulullah, perintahkan kepada Abbad bin Bisyir supaya membunuhnya.” Tetapi Rasulullah menjawab: “Umar, bagaimana kalau sampai menjadi pembicaraan orang, bahwa Muhammad membunuh sahabat-sahabatnya sendiri. Lalu ia meminta diumumkan supaya kaum Muslimin segera berangkat pada waktu yang tidak biasa mereka lakukan.” [2]</p><p>Jadi nabi tidak membunuh Ubay bin Salul karena takut apa kata orang.</p><p>Kisah terakhir adalah ketika Nabi berjalan bersama istrinya pada malam hari yang gelap. Hadistnya sebagai berikut: "Rasulullah shallallahu ‘alaihi wa sallam pernah beriktikaf di masjid, lantas aku (shafiyah) mengunjungi beliau pada malam hari lalu berbincang-bincang dengan beliau, lalu aku berdiri. Kemudian Nabi shallallahu ‘alaihi wa sallam mengantarkanku pulang ke rumah.” </p><p>Rumah Shafiyyah Ketika itu di rumah Usamah bin Yazid. Ketika mengantarkan pulang, lewatlah dua orang Anshar di jalan. Dua orang Anshar itu memandang Nabi shallallahu ‘alaihi wa sallam (dengan penuh curiga), kemudian mereka bergegas melewati Nabi shallallahu ‘alaihi wa sallam. Nabi shallallahu ‘alaihi wa sallam pun berkata, “Tak perlu curiga seperti itu, ini adalah istriku Shafiyyah binti Huyay.” Mereka berdua pun mengatakan, “Subhanallah, wahai Rasulullah.” Nabi shallallahu ‘alaihi wa sallam pun bersabda, “Sesungguhnya setan mengalir dalam diri manusia melalui pembuluh darahnya. Aku benar-benar khawatir ada sesuatu prasangka jelek yang ada dalam diri kalian berdua" [3].</p><p>Dari cerita di atas, filter sederhana untuk kapan mendengarkan apa kata orang adalah dengan melihat dampak/akibat yang kita terima dari mendengarkan atau tidak mendengarkan kata orang tersebut. Jika terjadi dampak besar (fitnah, masuk neraka, dll) maka kita perlu mengambil mana yang bisa menghindari dampak buruk tersebut. Misal dalam kasus Abu Thalib dan kisah bapak, anak, dan keledai, sudah seharusnya mereka tidak mendengarkan apa kata orang. Sebaliknya, bila dampaknya besar, kita mungkin perlu mendengar apa kata orang.</p><p>Referensi:</p><p>[1] https://www.kisahweb.com/2021/03/ini-5-hikmah-dari-cerita-kisah-bapak.html</p><p>[2] https://kalam.sindonews.com/read/67896/70/tatkala-umar-marah-dan-berniat-membunuh-dedengkot-munafik-ibnu-ubay-1591963573?showpage=all</p><p>[3] https://rumaysho.com/25497-40-kiat-agar-tidak-diganggu-setan-lakukanlah-amalan-amalan-ini.html</p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-90982991443157462422023-09-11T04:27:00.006+07:002023-12-22T20:00:35.463+07:00Changing Background of MOC Player to Transparent<p>The default background of MOC player (mocp) is ugly, see figure below. To change the default background of mocp, we can do two steps below.</p><p>Step 1: Add theme to MOC configuration file in ~/.moc/config</p>
<pre>XTermTheme = transparent-background
</pre>
Step 2: Change file permission (to not allow other tha n user, group, to write)
<pre>$ chmod g-w ~/.moc/config/
</pre>
That command will remove the permission of group (g) to write (-w). <br />
List of available (default) themes:
<br />
<ul style="text-align: left;"><li>black_theme</li><li>green_theme</li><li>red_theme</li><li>darkdot_theme</li><li>moca_theme</li><li>transparent-background</li><li>example_theme</li><li>nightly_theme</li><li>yellow_red_theme</li></ul><p>The figures below show the change of theme from default to <b>transparent-background</b>. <br /></p><p>Before</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9f7yI82oFOlww5Jaeyl-YG2nvSv4Be2QK0Qa9PERhnDQtaH4ZtCgsE3wK4FPw1tYe7dSmxKek8PHRoxXtyAzW_Nh0EZHCDPtsCl6VpwLifGUzC3TNxyPaI0yLkhNZIe_AQlnYRzdMTOMHxHmUo7aQgWZZSOqwaceCTGuUEjyeMZx2YMhiNsBJO6tQEX4/s946/moc_old.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="MOC Player default theme" border="0" data-original-height="629" data-original-width="946" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9f7yI82oFOlww5Jaeyl-YG2nvSv4Be2QK0Qa9PERhnDQtaH4ZtCgsE3wK4FPw1tYe7dSmxKek8PHRoxXtyAzW_Nh0EZHCDPtsCl6VpwLifGUzC3TNxyPaI0yLkhNZIe_AQlnYRzdMTOMHxHmUo7aQgWZZSOqwaceCTGuUEjyeMZx2YMhiNsBJO6tQEX4/w640-h426/moc_old.png" width="640" /></a></div>
After (with Terminal's Solarized theme)
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6QGOY4Gq0RMJQztz_iNtyX0GJGkownxvj1BSVR-1UvknV8jqVgqMvrJffTKk04xD5jutF_5w9d_DTiKBSL8mC8V7TIpL1jjgG8ZnpWkAzsnqZxgo3_0SgnAaw18tP1mZacWyT93KJrm4cTJa8q6PdKDLH00_LXSqPBS9NFLnk7u6XlvZ1adjl36ePJFM/s946/mocp_new.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="MOC Player transparent theme" border="0" data-original-height="629" data-original-width="946" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6QGOY4Gq0RMJQztz_iNtyX0GJGkownxvj1BSVR-1UvknV8jqVgqMvrJffTKk04xD5jutF_5w9d_DTiKBSL8mC8V7TIpL1jjgG8ZnpWkAzsnqZxgo3_0SgnAaw18tP1mZacWyT93KJrm4cTJa8q6PdKDLH00_LXSqPBS9NFLnk7u6XlvZ1adjl36ePJFM/w640-h426/mocp_new.png" width="640" /></a></div>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-34315371920223753362023-08-25T12:37:00.010+07:002024-01-12T08:30:08.436+07:00Mencoba TTS Bahasa Indonesia dengan VITs dan Meta MMS<p>Sudah lama saya ingin mencoba (membuat) teknologi <b><i>text-to-speech (TTS)</i></b> atau <i>speech synthesis</i> bahasa Indonesia. Percobaan pertama saya beberapa tahun lalu gagal. Disini reponya: <a href="https://github.com/bagustris/Expressive-FastSpeech2" target="_blank">Expressive-FastSpeech2</a>. Pada percobaan tersebut, saya langsung mencoba membuat suara (bukan Bahasa Indonesia) yang memiliki emosi, seperti suara orang marah, sedih, atau senang. Alih-alih suara, saya hanya mendengar derau/bising saja dari algoritma FastSpeech2.</p><p>Ketika Meta/Facebook mengumumkan salah satu riset mereka, yakni <a href="https://github.com/facebookresearch/fairseq/blob/main/examples/mms/README.md" target="_blank">MMS (Massively Multilingual Speech)</a>, saya langsung tertarik mencobanya. MMS bisa diaplikasikan untuk ASR (automatic speech recognition, atau STT, speech-to-text) dan TTS. Untuk TTS, sepemahaman saya, Meta hanya mengaplikasikan dataset yang besar pada Variational Inference with adversarial learning for end-to-end Text-to-Speech (VITS). Saya coba ASRnya tidak lebih baik dari OpenAI Whisper, khususnya dari sisi <i>latency</i>. Saya coba TTSnya, kebetulan hasilnya memuaskan, khususnya untuk yang belum pernah berhasil membuat TTS sendiri.</p><h4 style="text-align: left;">Repository</h4><p>Untuk keperluan TTS ini, saya buat repository khusus di Github: <a href="https://github.com/bagustris/tts-bahasa" target="_blank">TTS-Bahasa</a>. TTS-Bahasa sebenarnya tidak khusus untuk bahasa Indonesia, tapi semua bahasa yang didukung oleh MMS (ada lebih dari 1000 bahasa). Repo tersebut saya adaptasi dari tutorial di laman MMS, yakni <a href="https://github.com/facebookresearch/fairseq/blob/main/examples/mms/tts/tutorial/MMS_TTS_Inference_Colab.ipynb" target="_blank">tutorial Google Colabnya</a>. Saya hanya menambahkan satu skrip python CLI (command line interface) untuk memudahkan pembuatan audio file suara sintesis berdasarkan input kalimat. Contohnya seperti ini.</p>
<pre>python3 mms_tts_ind.py --text "Selamat datang di Indonesia"</pre>
Suara berbahasa Indonesia akan diperdengarkan setelah eksekusi program selesai (berbunyi: "Selamat datang di Indonesia"). Luaran suara tersebut juga bisa disimpan dalam format WAV atau MP3, misalnya.
<pre>python3 mms_tts_ind.py --text "Selamat datang di Indonesia" -s -o selamat_datang.wav </pre>
Untuk mencobanya, tidak perlu menginstall. Cukup clone repo tersebut, dan ikuti petunjuk di READMEnya. Jika ada kendala, anda bisa membuka "issues" di repo tersebut.<div><br /></div><h4 style="text-align: left;">Demo</h4><div>Jika anda bukan programmer, coder, researcher, mahasiswa teknik, atau tidak terbiasa dengan Python, anda bisa langsung mencoba demo-nya disini: <a href="https://bagustris.github.io/tts-bahasa">https://bagustris.github.io/tts-bahasa</a>/.</div>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-30547548594567473412023-08-08T20:30:00.007+07:002023-08-25T12:44:09.476+07:00Menginstall ESPNET via Conda<p>Tulisan berikut merupakan catatan singkat instalasi ESPNET dengan Conda (OS: Ubuntu 20.04~).</p><p>Dari <a href="https://espnet.github.io/espnet/installation.html" target="_blank">dokumentasi ESPNET</a>, cara yang disarankan untuk menginsall ESPNET adalah melalui Conda.</p>
<pre>./setup_anaconda.sh miniconda espnet 3.8
</pre>
Namun dengan cara ini, <a href="https://stackoverflow.com/questions/57527131/conda-environment-has-no-name-visible-in-conda-env-list-how-do-i-activate-it-a" target="_blank">environment conda menjadi tidak bernama</a> sehingga kita perlu me-load conda dengan fullpath.
Solusinya adalah dengan memberikan argumen yang tepat untuk `setup_anaconda.sh`, yakni <code>$CONDA_ROOT</code>. Pada Ubuntu, default CONDA_ROOT ada di `/home/$USER/miniconda3` (Setelah menginstall miniconda). Contohnya adalah sebagai berikut.
<pre>./setup_anaconda.sh /home/bagus/miniconda3/ espnet 3.9
</pre><p>
Dengan cara ini kita bisa berpindah ke perintah instalasi selanjutnya, yakni `make`. Setelah terinstall, kita bisa mengaktifkan ESPNET dengan `conda activate espnet`. </p><p> </p><p>Catatan:</p><p>- Sebelum menginstall ESPNET, kita perlu menginstall cmake, python3-dev, sox, flac, dan build-essential via apt-get. <br /></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-66448225232311002492023-08-05T04:15:00.002+07:002023-08-07T15:10:46.050+07:00Melanggan Medium<p>Minggu ini saya memutuskan untuk melanggan Medium. Biaya langganannya 5 USD/bulan. Medium, bagi yang belum tahu, adalah platform penerbitan daring yang menyediakan ruang bagi penulis dari berbagai bidang untuk berbagi pandangan, pengetahuan, cerita, dan pengalaman mereka. Saya tertarik dengan Medium karena menawarkan beragam konten menarik, dari esai inspiratif hingga artikel informatif yang membahas berbagai topik. <br /></p><p>Ada beberapa alasan kuat mengapa saya memutuskan untuk melanggan Medium untuk setahun kedepan: </p><ul style="text-align: left;"><li>Beberapa konten dengan kualitas tinggi hanya bisa diakses dengan melanggan. Medium menempatkan kualitas konten di atas hal lain; banyak penulisnya adalah penulis buku. Mereka menggali topik dengan mendalam dan menawarkan sudut pandang yang unik, membuat saya selalu terinspirasi dan berpikir lebih jauh. </li><li>Bisa dibayar dari program partner. Agar mendapatkan bayaran dari artikel yang kita tulis, kita harus menjadi pelanggan melalui <a href="https://medium.com/partner-program" target="_blank">Medium Partner Program.</a> <br /></li><li>Beragam Topik yang Menarik: Medium menawarkan berbagai macam topik yang bisa dipilih sesuai minat dan hobi saya. Entah itu teknologi, pengembangan diri, psikologi, budaya, atau bisnis, saya selalu menemukan konten yang relevan dan bermanfaat bagi pengetahuan saya. </li><li>Komunitas dan Interaksi: Medium juga memiliki komunitas yang aktif dan ramah. Saya senang membaca komentar dan tanggapan dari pembaca lain yang menambah wawasan saya tentang suatu topik. Selain itu, Medium memiliki fitur "clap" yang memungkinkan saya untuk memberikan apresiasi atas tulisan yang saya nikmati. </li><li>Memotivasi untuk menulis lebih. Saya pernah menulis untuk menulis satu artikel per minggu (<a href="https://bagustris.blogspot.com/2020/03/new-article-every-weekend.html">https://bagustris.blogspot.com/2020/03/new-article-every-weekend.html</a>). Namun, hal ini sangat sulit ternyata! Dengan medium, saya berharap target ini bisa tercapai (logika: karena berbayar saya harus menulis, tidak saja membacanya).<br /></li></ul><p>Saya akan lihat (evaluasi) setahun mendatang apakah Medium ini memberikan benefit yang lebih dari 5 USD/per bulan. Harapan saya untuk setahun mendatang adalah: </p><ol style="text-align: left;"><li>Lebih Banyak Artikel saya yang Menarik: Saya berharap untuk menemukan lebih banyak artikel yang mendalam dan berbobot di Medium. Semakin banyak penulis berbakat yang bergabung dan berkontribusi, semakin kaya pula konten yang akan tersedia bagi para pembaca. </li><li>Pengembangan Diri sebagai Penulis (baik dari sisi kuantitas dan kualitas): Dengan membaca dan belajar dari penulis-penulis hebat di Medium, saya berharap untuk terus mengembangkan kemampuan menulis saya sendiri. Saya ingin mengasah kemampuan untuk menyajikan informasi dengan cara yang menarik dan dapat dipahami oleh pembaca. </li><li>Berbagi Kontribusi yang berdampak: Saya bermimpi suatu hari nanti bisa berkontribusi dengan menulis artikel berdampak tinggi di Medium. Bagaimana mengukur dampaknya? Medium menyediakan statistik siapa yang hanya melihat artikel kita dan siapa yang benar-benar membaca artikel kita. Metrik kedua ini yang saya kejar.<br /></li><li>Menjalin Lebih Banyak Koneksi: Medium adalah tempat yang tepat untuk menjalin hubungan dan koneksi dengan penulis dan pembaca dari seluruh dunia. Saya berharap bisa berinteraksi lebih banyak dengan mereka, berdiskusi, dan berbagi inspirasi. </li></ol>Demikianlah cerita mengapa saya memilih untuk melanggan Medium.com dan harapan saya untuk tahun mendatang.Selanjutnya, tulisan-tulisan dalam bahasa Indonesia akan saya tulis di Blogger ini sedangkan artikel bahasa Inggris akan saya tulis di <a href="https://medium.com/@btatmaja" target="_blank">akun Medium saya</a>.<br />bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-42281059541917470232023-07-25T15:20:00.008+07:002023-07-27T10:04:31.457+07:00Live microphone visualization (waveform) with sounddevice<p> *** This post was made by ChatGPT***</p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="407" src="https://www.youtube.com/embed/Os8oVbwCxaI" width="489" youtube-src-id="Os8oVbwCxaI"></iframe></div><br />
<p>Are you interested in visualizing live audio data from your microphone? Do you want to see the waveform of your voice or any other sound in real time? In this blog post, we’ll explore a Python script that utilizes Matplotlib to plot live microphone signals. This script is a useful tool for understanding and analyzing audio input in real time.</p>
<p>Before we begin, make sure you have sounddevice, Matplotlib, and NumPy installed. If not, you can install them using the following command:</p>
<pre><code>pip install matplotlib numpy sounddevice</code></pre>
<p>Now, let’s dive into the code and see how it works.</p>
<h3 id="the-code">The Code</h3>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a aria-hidden="true" href="#cb2-1"></a><span class="co">#!/usr/bin/env python3</span></span>
<span id="cb2-2"><a aria-hidden="true" href="#cb2-2"></a><span class="co">"""Plot the live microphone signal(s) with matplotlib.</span></span>
<span id="cb2-3"><a aria-hidden="true" href="#cb2-3"></a></span>
<span id="cb2-4"><a aria-hidden="true" href="#cb2-4"></a><span class="co">Matplotlib and NumPy have to be installed.</span></span>
<span id="cb2-5"><a aria-hidden="true" href="#cb2-5"></a></span>
<span id="cb2-6"><a aria-hidden="true" href="#cb2-6"></a><span class="co">"""</span></span>
<span id="cb2-7"><a aria-hidden="true" href="#cb2-7"></a><span class="im">import</span> argparse</span>
<span id="cb2-8"><a aria-hidden="true" href="#cb2-8"></a><span class="im">import</span> queue</span>
<span id="cb2-9"><a aria-hidden="true" href="#cb2-9"></a><span class="im">import</span> sys</span>
<span id="cb2-10"><a aria-hidden="true" href="#cb2-10"></a></span>
<span id="cb2-11"><a aria-hidden="true" href="#cb2-11"></a><span class="im">from</span> matplotlib.animation <span class="im">import</span> FuncAnimation</span>
<span id="cb2-12"><a aria-hidden="true" href="#cb2-12"></a><span class="im">import</span> matplotlib.pyplot <span class="im">as</span> plt</span>
<span id="cb2-13"><a aria-hidden="true" href="#cb2-13"></a><span class="im">import</span> numpy <span class="im">as</span> np</span>
<span id="cb2-14"><a aria-hidden="true" href="#cb2-14"></a><span class="im">import</span> sounddevice <span class="im">as</span> sd</span></code></pre></div>
<p>The script starts with the usual shebang (<code>#!/usr/bin/env python3</code>) and a brief docstring explaining the purpose of the code. It also imports the necessary modules: <code>argparse</code>, <code>queue</code>, <code>sys</code>, <code>FuncAnimation</code> from <code>matplotlib.animation</code>, <code>plt</code> (alias for <code>matplotlib.pyplot</code>), <code>numpy</code>, and <code>sounddevice</code>.</p>
<p>Next, the code defines two helper functions and two main functions.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a aria-hidden="true" href="#cb3-1"></a><span class="kw">def</span> int_or_str(text):</span>
<span id="cb3-2"><a aria-hidden="true" href="#cb3-2"></a> <span class="co">"""Helper function for argument parsing."""</span></span>
<span id="cb3-3"><a aria-hidden="true" href="#cb3-3"></a> <span class="cf">try</span>:</span>
<span id="cb3-4"><a aria-hidden="true" href="#cb3-4"></a> <span class="cf">return</span> <span class="bu">int</span>(text)</span>
<span id="cb3-5"><a aria-hidden="true" href="#cb3-5"></a> <span class="cf">except</span> <span class="pp">ValueError</span>:</span>
<span id="cb3-6"><a aria-hidden="true" href="#cb3-6"></a> <span class="cf">return</span> text</span>
<span id="cb3-7"><a aria-hidden="true" href="#cb3-7"></a></span>
<span id="cb3-8"><a aria-hidden="true" href="#cb3-8"></a></span>
<span id="cb3-9"><a aria-hidden="true" href="#cb3-9"></a><span class="kw">def</span> audio_callback(indata, frames, time, status):</span>
<span id="cb3-10"><a aria-hidden="true" href="#cb3-10"></a> <span class="co">"""This is called (from a separate thread) for each audio block."""</span></span>
<span id="cb3-11"><a aria-hidden="true" href="#cb3-11"></a> <span class="cf">if</span> status:</span>
<span id="cb3-12"><a aria-hidden="true" href="#cb3-12"></a> <span class="bu">print</span>(status, <span class="bu">file</span><span class="op">=</span>sys.stderr)</span>
<span id="cb3-13"><a aria-hidden="true" href="#cb3-13"></a> <span class="co"># Fancy indexing with mapping creates a (necessary!) copy:</span></span>
<span id="cb3-14"><a aria-hidden="true" href="#cb3-14"></a> q.put(indata[::args.downsample, mapping])</span></code></pre></div>
<p>The <code>int_or_str</code> function is a helper used for parsing command-line arguments. It tries to convert the input text to an integer and returns it if successful; otherwise, it returns the input text as it is.</p>
<p>The <code>audio_callback</code> function is called for each audio block received from the microphone. It receives <code>indata</code> (the audio data), <code>frames</code> (the number of frames), <code>time</code> (the timestamp of the audio data), and <code>status</code> (the status of the audio stream). It prints any status messages to the standard error and puts a copy of the audio data (filtered using downsampling and channel mapping) into a queue (<code>q</code>) for processing later.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a aria-hidden="true" href="#cb4-1"></a><span class="kw">def</span> update_plot(frame):</span>
<span id="cb4-2"><a aria-hidden="true" href="#cb4-2"></a> <span class="co">"""This is called by matplotlib for each plot update.</span></span>
<span id="cb4-3"><a aria-hidden="true" href="#cb4-3"></a></span>
<span id="cb4-4"><a aria-hidden="true" href="#cb4-4"></a><span class="co"> Typically, audio callbacks happen more frequently than plot updates,</span></span>
<span id="cb4-5"><a aria-hidden="true" href="#cb4-5"></a><span class="co"> therefore the queue tends to contain multiple blocks of audio data.</span></span>
<span id="cb4-6"><a aria-hidden="true" href="#cb4-6"></a></span>
<span id="cb4-7"><a aria-hidden="true" href="#cb4-7"></a><span class="co"> """</span></span>
<span id="cb4-8"><a aria-hidden="true" href="#cb4-8"></a> <span class="kw">global</span> plotdata</span>
<span id="cb4-9"><a aria-hidden="true" href="#cb4-9"></a> <span class="cf">while</span> <span class="va">True</span>:</span>
<span id="cb4-10"><a aria-hidden="true" href="#cb4-10"></a> <span class="cf">try</span>:</span>
<span id="cb4-11"><a aria-hidden="true" href="#cb4-11"></a> data <span class="op">=</span> q.get_nowait()</span>
<span id="cb4-12"><a aria-hidden="true" href="#cb4-12"></a> <span class="cf">except</span> queue.Empty:</span>
<span id="cb4-13"><a aria-hidden="true" href="#cb4-13"></a> <span class="cf">break</span></span>
<span id="cb4-14"><a aria-hidden="true" href="#cb4-14"></a> shift <span class="op">=</span> <span class="bu">len</span>(data)</span>
<span id="cb4-15"><a aria-hidden="true" href="#cb4-15"></a> plotdata <span class="op">=</span> np.roll(plotdata, <span class="op">-</span>shift, axis<span class="op">=</span><span class="dv">0</span>)</span>
<span id="cb4-16"><a aria-hidden="true" href="#cb4-16"></a> plotdata[<span class="op">-</span>shift:, :] <span class="op">=</span> data</span>
<span id="cb4-17"><a aria-hidden="true" href="#cb4-17"></a> <span class="cf">for</span> column, line <span class="kw">in</span> <span class="bu">enumerate</span>(lines):</span>
<span id="cb4-18"><a aria-hidden="true" href="#cb4-18"></a> line.set_ydata(plotdata[:, column])</span>
<span id="cb4-19"><a aria-hidden="true" href="#cb4-19"></a> <span class="cf">return</span> lines</span></code></pre></div>
<p>The <code>update_plot</code> function is called by Matplotlib for each plot update. It retrieves audio data from the queue (<code>q</code>) and shifts the existing data to accommodate the new audio block. The function then updates the y-data of the lines on the plot with the new audio data.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a aria-hidden="true" href="#cb5-1"></a><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:</span>
<span id="cb5-2"><a aria-hidden="true" href="#cb5-2"></a> <span class="co"># ... (continued in the next code block)</span></span></code></pre></div>
<p>The script uses the standard Python <code>if __name__ == "__main__":</code> guard to ensure that the following code is only executed when the script is run directly, not when it’s imported as a module.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a aria-hidden="true" href="#cb6-1"></a> parser <span class="op">=</span> argparse.ArgumentParser(add_help<span class="op">=</span><span class="va">False</span>)</span>
<span id="cb6-2"><a aria-hidden="true" href="#cb6-2"></a> parser.add_argument(</span>
<span id="cb6-3"><a aria-hidden="true" href="#cb6-3"></a> <span class="st">'-l'</span>, <span class="st">'--list-devices'</span>, action<span class="op">=</span><span class="st">'store_true'</span>,</span>
<span id="cb6-4"><a aria-hidden="true" href="#cb6-4"></a> <span class="bu">help</span><span class="op">=</span><span class="st">'show list of audio devices and exit'</span>)</span>
<span id="cb6-5"><a aria-hidden="true" href="#cb6-5"></a> args, remaining <span class="op">=</span> parser.parse_known_args()</span>
<span id="cb6-6"><a aria-hidden="true" href="#cb6-6"></a> <span class="cf">if</span> args.list_devices:</span>
<span id="cb6-7"><a aria-hidden="true" href="#cb6-7"></a> <span class="bu">print</span>(sd.query_devices())</span>
<span id="cb6-8"><a aria-hidden="true" href="#cb6-8"></a> parser.exit(<span class="dv">0</span>)</span></code></pre></div>
<p>The code sets up an argument parser with <code>argparse</code> to handle command-line arguments. It allows the user to list available audio devices and exit the program without running the main functionality. If the user specifies the <code>--list-devices</code> flag, the script will print a list of audio devices using <code>sd.query_devices()</code> and then exit.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb7-1"><a aria-hidden="true" href="#cb7-1"></a> parser <span class="op">=</span> argparse.ArgumentParser(</span>
<span id="cb7-2"><a aria-hidden="true" href="#cb7-2"></a> description<span class="op">=</span>__doc__,</span>
<span id="cb7-3"><a aria-hidden="true" href="#cb7-3"></a> formatter_class<span class="op">=</span>argparse.RawDescriptionHelpFormatter,</span>
<span id="cb7-4"><a aria-hidden="true" href="#cb7-4"></a> parents<span class="op">=</span>[parser])</span>
<span id="cb7-5"><a aria-hidden="true" href="#cb7-5"></a> parser.add_argument(</span>
<span id="cb7-6"><a aria-hidden="true" href="#cb7-6"></a> <span class="st">'channels'</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">int</span>, default<span class="op">=</span>[<span class="dv">1</span>], nargs<span class="op">=</span><span class="st">'*'</span>, metavar<span class="op">=</span><span class="st">'CHANNEL'</span>,</span>
<span id="cb7-7"><a aria-hidden="true" href="#cb7-7"></a> <span class="bu">help</span><span class="op">=</span><span class="st">'input channels to plot (default: the first)'</span>)</span>
<span id="cb7-8"><a aria-hidden="true" href="#cb7-8"></a> parser.add_argument(</span>
<span id="cb7-9"><a aria-hidden="true" href="#cb7-9"></a> <span class="st">'-d'</span>, <span class="st">'--device'</span>, <span class="bu">type</span><span class="op">=</span>int_or_str,</span>
<span id="cb7-10"><a aria-hidden="true" href="#cb7-10"></a> <span class="bu">help</span><span class="op">=</span><span class="st">'input device (numeric ID or substring)'</span>)</span>
<span id="cb7-11"><a aria-hidden="true" href="#cb7-11"></a> parser.add_argument(</span>
<span id="cb7-12"><a aria-hidden="true" href="#cb7-12"></a> <span class="st">'-w'</span>, <span class="st">'--window'</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">float</span>, default<span class="op">=</span><span class="dv">200</span>, metavar<span class="op">=</span><span class="st">'DURATION'</span>,</span>
<span id="cb7-13"><a aria-hidden="true" href="#cb7-13"></a> <span class="bu">help</span><span class="op">=</span><span class="st">'visible time slot (default: </span><span class="sc">%(default)s</span><span class="st"> ms)'</span>)</span>
<span id="cb7-14"><a aria-hidden="true" href="#cb7-14"></a> parser.add_argument(</span>
<span id="cb7-15"><a aria-hidden="true" href="#cb7-15"></a> <span class="st">'-i'</span>, <span class="st">'--interval'</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">float</span>, default<span class="op">=</span><span class="dv">30</span>,</span>
<span id="cb7-16"><a aria-hidden="true" href="#cb7-16"></a> <span class="bu">help</span><span class="op">=</span><span class="st">'minimum time between plot updates (default: </span><span class="sc">%(default)s</span><span class="st"> ms)'</span>)</span>
<span id="cb7-17"><a aria-hidden="true" href="#cb7-17"></a> parser.add_argument(</span>
<span id="cb7-18"><a aria-hidden="true" href="#cb7-18"></a> <span class="st">'-b'</span>, <span class="st">'--blocksize'</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">int</span>, <span class="bu">help</span><span class="op">=</span><span class="st">'block size (in samples)'</span>)</span>
<span id="cb7-19"><a aria-hidden="true" href="#cb7-19"></a> parser.add_argument(</span>
<span id="cb7-20"><a aria-hidden="true" href="#cb7-20"></a> <span class="st">'-sr'</span>, <span class="st">'--samplerate'</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">float</span>, default<span class="op">=</span><span class="dv">16000</span>, <span class="bu">help</span><span class="op">=</span><span class="st">'sampling rate of audio device'</span>)</span>
<span id="cb7-21"><a aria-hidden="true" href="#cb7-21"></a> parser.add_argument(</span>
<span id="cb7-22"><a aria-hidden="true" href="#cb7-22"></a> <span class="st">'-n'</span>, <span class="st">'--downsample'</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">int</span>, default<span class="op">=</span><span class="dv">1</span>, metavar<span class="op">=</span><span class="st">'N'</span>,</span>
<span id="cb7-23"><a aria-hidden="true" href="#cb7-23"></a> <span class="bu">help</span><span class="op">=</span><span class="st">'No downsample (default: </span><span class="sc">%(default)s</span><span class="st">)'</span>)</span>
<span id="cb7-24"><a aria-hidden="true" href="#cb7-24"></a> args <span class="op">=</span> parser.parse_args(remaining)</span></code></pre></div>
<p>The script creates another argument parser, this time with a description based on the script’s docstring. It defines several command-line arguments:</p>
<ul>
<li><code>channels</code>: The channels to plot. If not specified, it will default to the first channel.</li>
<li><code>device</code>: The input audio device to use. It can be specified either by a numeric ID or a substring of the device name.</li>
<li><code>window</code>: The visible time slot in milliseconds. This controls how much of the audio history is displayed on the plot.</li>
<li><code>interval</code>: The minimum time between plot updates in milliseconds.</li>
<li><code>blocksize</code>: The block size (number of samples) for audio processing. If not specified, the default block size of the audio stream will be used.</li>
<li><code>samplerate</code>: The sampling rate of the audio device. If not specified, it will default to 16000 Hz.</li>
<li><code>downsample</code>: The factor by which the audio data is downsampled. By default, no downsampling is applied.</li>
</ul>
<p>The <code>parse_args</code> method is called to parse the remaining command-line arguments (<code>remaining</code>) after handling the <code>--list-devices</code> option.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb8-1"><a aria-hidden="true" href="#cb8-1"></a> <span class="cf">if</span> <span class="bu">any</span>(c <span class="op"><</span> <span class="dv">1</span> <span class="cf">for</span> c <span class="kw">in</span> args.channels):</span>
<span id="cb8-2"><a aria-hidden="true" href="#cb8-2"></a> parser.error(<span class="st">'argument CHANNEL: must be >= 1'</span>)</span>
<span id="cb8-3"><a aria-hidden="true" href="#cb8-3"></a> mapping <span class="op">=</span> [c <span class="op">-</span> <span class="dv">1</span> <span class="cf">for</span> c <span class="kw">in</span> args.channels] <span class="co"># Channel numbers start with 1</span></span>
<span id="cb8-4"><a aria-hidden="true" href="#cb8-4"></a> q <span class="op">=</span> queue.Queue()</span></code></pre></div>
<p>The code checks if any of the specified channels are less than 1. If so, it raises an error with an appropriate message. It then creates a mapping list for the channel indices, as the channel numbers in <code>args.channels</code> start from 1.</p> Full code is listed below. Actually, it is based on an example from sounddevice documentation [1].
<pre class="prettyprint">#!/usr/bin/env python3
"""Plot the live microphone signal(s) with matplotlib.
Matplotlib and NumPy have to be installed.
"""
import argparse
import queue
import sys
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
import sounddevice as sd
def int_or_str(text):
"""Helper function for argument parsing."""
try:
return int(text)
except ValueError:
return text
def audio_callback(indata, frames, time, status):
"""This is called (from a separate thread) for each audio block."""
if status:
print(status, file=sys.stderr)
# Fancy indexing with mapping creates a (necessary!) copy:
q.put(indata[::args.downsample, mapping])
def update_plot(frame):
"""This is called by matplotlib for each plot update.
Typically, audio callbacks happen more frequently than plot updates,
therefore the queue tends to contain multiple blocks of audio data.
"""
global plotdata
while True:
try:
data = q.get_nowait()
except queue.Empty:
break
shift = len(data)
plotdata = np.roll(plotdata, -shift, axis=0)
plotdata[-shift:, :] = data
for column, line in enumerate(lines):
line.set_ydata(plotdata[:, column])
return lines
if __name__ == "__main__":
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument(
'-l', '--list-devices', action='store_true',
help='show list of audio devices and exit')
args, remaining = parser.parse_known_args()
if args.list_devices:
print(sd.query_devices())
parser.exit(0)
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[parser])
parser.add_argument(
'channels', type=int, default=[1], nargs='*', metavar='CHANNEL',
help='input channels to plot (default: the first)')
parser.add_argument(
'-d', '--device', type=int_or_str,
help='input device (numeric ID or substring)')
parser.add_argument(
'-w', '--window', type=float, default=200, metavar='DURATION',
help='visible time slot (default: %(default)s ms)')
parser.add_argument(
'-i', '--interval', type=float, default=30,
help='minimum time between plot updates (default: %(default)s ms)')
parser.add_argument(
'-b', '--blocksize', type=int, help='block size (in samples)')
parser.add_argument(
'-sr', '--samplerate', type=float, default=16000, help='sampling rate of audio device')
parser.add_argument(
'-n', '--downsample', type=int, default=1, metavar='N',
help='No downsample (default: %(default)s)')
args = parser.parse_args(remaining)
if any(c < 1 for c in args.channels):
parser.error('argument CHANNEL: must be >= 1')
mapping = [c - 1 for c in args.channels] # Channel numbers start with 1
q = queue.Queue()
try:
if args.samplerate is None:
device_info = sd.query_devices(args.device, 'input')
args.samplerate = device_info['default_samplerate']
length = int(args.window * args.samplerate / (1000 * args.downsample))
plotdata = np.zeros((length, len(args.channels)))
fig, ax = plt.subplots()
lines = ax.plot(plotdata)
if len(args.channels) > 1:
ax.legend([f'channel {c}' for c in args.channels],
loc='lower left', ncol=len(args.channels))
ax.axis((0, len(plotdata), -1, 1))
ax.set_yticks([0])
ax.yaxis.grid(True)
ax.tick_params(bottom=False, top=False, labelbottom=False,
right=False, left=False, labelleft=False)
ax.text(0.01, 0.99, f'Sample rate: {args.samplerate/args.downsample} Hz', transform=ax.transAxes, va='top', ha='left')
fig.tight_layout(pad=0)
stream = sd.InputStream(
device=args.device, channels=max(args.channels),
samplerate=args.samplerate, callback=audio_callback)
ani = FuncAnimation(fig, update_plot, interval=args.interval, blit=True)
with stream:
plt.show()
except Exception as e:
parser.exit(type(e).__name__ + ': ' + str(e))
</pre>
Save it as sd_plot_input.py (or whatever name.py) and run it with the following commands. See the video above for the sample output.<br /><pre>$ python3 sd_plot_input.py</pre><p>
<br />
Reference: </p><ol style="text-align: left;"><li>https://python-sounddevice.readthedocs.io/en/0.4.6/examples.html#plot-microphone-signal-s-in-real-time<br /></li></ol>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-22354197823329323222023-07-20T13:42:00.005+07:002024-01-12T08:31:49.819+07:00Memilih default Kernel Linux di Ubuntu (22.04)<p>Setelah upgrade ke kernel 5.19, terjadi masalah "screen flickering" pada Laptop (kantor) saya, Dell XPS 9320. Padahal laptop ini adalah certified hardware, Link: https://ubuntu.com/certified/202112-29761. Hanya saja Canonical sudah berdalih, karena saya membelinya dengan pre-installed Windows (11), bukan Ubuntu.</p><blockquote><p>...Standard images of Ubuntu may not work well, or at all. (https://ubuntu.com/certified/202112-29761)</p></blockquote><p>Karena menyebabkan sakit mata jika screen flickering ini dibiarkan, saya mencari solusinya. Biasanya ini adalah permasalahan yang disebabkan karena update kernel, dan benar saja AskUbuntu memberikan jawaban yang serupa:</p><p> </p><blockquote><p>https://askubuntu.com/questions/1455799/ubuntu-22-04-2-screen-flickering-glitches.</p></blockquote><p> </p>Untuk mengecek kernel di Ubuntu, saya menggunakan perintah berikut.
<pre>$ uname -a
Linux bagus-XPS-9320 linux-image-5.19.0-46-generic #6-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 24 18:24:09 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
</pre>
Permasalahannya ada di kernel 5.19 yang saya gunakan tersebut.<div>
<br />Untuk melihat list kernel yang tersedia bisa dengan cara berikut (bisa juga lewat Advanced options saat booting).
<pre>$ sudo apt list --installed | grep linux-image
linux-image-5.15.0-60-generic/now 5.15.0-60.66 amd64 [installed,local]
linux-image-5.19.0-46-generic/jammy-updates,jammy-security,now 5.19.0-46.47~22.04.1 amd64 [installed,automatic]
linux-image-6.0.0-1012-oem/now 6.0.0-1012.12 amd64 [installed,local]
linux-image-6.1.0-1006-oem/now 6.1.0-1006.6 amd64 [installed,local]
linux-image-generic-hwe-22.04/jammy-updates,jammy-security,now 5.19.0.46.47~22.04.21 amd64 [installed,automatic]
bagus@xps-9320:~$
</pre>
<p>Solusinya adalah mengganti kernel. Cara pertama untuk mengetes solusi ini adalah reboot dan masuk ke Advanced options dan memilih kernel lain (dalam hal ini 6.1) dan cek apakah screen flickering masih terjadi.<br /></p>
Cara kedua adalah dengan mengganti kernel 5.19 menjadi <b>6.1 by-default </b>secara otomatis. Ini adalah yang saya gunakan, tapi carannya beda dengan cara yang diterangkan oleh AskUbuntu di atas (tapi didapat dari AskUbuntu lainnya [2]).
Pertama back-up file grub.
<pre>sudo cp /etc/default/grub /etc/default/grub.bak</pre>
Kedua edit `LINUX_DEFAULT=0` menjadi kernel yang dituju. Dalam hal ini saya menggunakan menu "Advanced options for Ubuntu" dan kernelnya, digabung dengan tanda ">". Berikut isi grub saya. Perhatikan dua baris teratas, baris pertama adalah konfigurasi lama (dikomen) dan baris kedua adalah konfigurasi baru.
<pre>$ sudo vim /etc/default/grub
#GRUB_DEFAULT=0
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.1.0-1006-oem"
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""
#GRUB_CMDLINE_LINUX_DEFAULT="i915.enable_dc=0 intel_idle.max_cstate=2"
</pre>
Terakhir adalah update-grub
<pre>$ sudo update-grub
</pre><p>
Dan reboot laptop. Setelah sekian lama mengetik tulisan ini, screen flickering tidak terjadi. </p><p><br />
Referensi: </p><ol style="text-align: left;"><li>https://askubuntu.com/questions/1455799/ubuntu-22-04-2-screen-flickering-glitches</li><li>https://askubuntu.com/questions/216398/set-older-kernel-as-default-grub-entry<br /></li></ol></div>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-55399275811425073072023-05-31T07:41:00.000+07:002023-05-31T07:41:59.413+07:00Kenapa tidak ada kursi bernomor I di pesawat?<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1rBMoGijAwRbb2fKruINJVI-QVmzpwq9qXbcA0eRlbAhgZ71rZEPpWFE_FSkS2lABRe4odS7tvJPYiRq3NY0rP9bvg0uxmNR2fPajbZtcRb6sOwFxYbyl7EHw3zOMV5os6xSUEs7BoAcyncExAegPhgxPdtWBI1t1hOsl98RGgmaQZlG9y8GgQNjx/s2901/image10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2863" data-original-width="2901" height="632" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1rBMoGijAwRbb2fKruINJVI-QVmzpwq9qXbcA0eRlbAhgZ71rZEPpWFE_FSkS2lABRe4odS7tvJPYiRq3NY0rP9bvg0uxmNR2fPajbZtcRb6sOwFxYbyl7EHw3zOMV5os6xSUEs7BoAcyncExAegPhgxPdtWBI1t1hOsl98RGgmaQZlG9y8GgQNjx/w640-h632/image10.png" width="640" /></a></div><br /><p></p><p><br /></p><p>Sudah lama saya bertanya-tanya, ketika naik pesawat, kenapa tidak ada nomor tempat duduk "I" di pesawat. Dan hari ini, ketika sesorang menanyakan hal itu (lebih tepatnya komplain), saya langsung googling. Jawaban Google, berdasarkan Wikipedia, adalah sebagai berikut:</p><blockquote><p>On many aircraft, the rightmost seats have letter designations HJK, skipping the letter I. This is because each seat has a row number followed by letter; letters that may be confused with numbers (I, O, Q, S, or Z) must be avoided, usually for people with dyslexia.</p></blockquote><p>Jadi jawabannya, kenapa tidak ada huruf I, juga tidak ada huruf O, Q, S, dan Z, di pesawat adalah untuk menghindari keambiguan.</p><p></p><blockquote><p>I ambigu dengan angka 1,</p><p>O dan Q ambigu dengan angka 0,</p><p>S ambigu dengan angka 5, dan</p><p>Z ambigu dengan angka 2.</p></blockquote><p></p><p>Orang dengan disleksia, kondisi di mana seseorang mengalami kesulitan belajar yang menyebabkan masalah pada proses menulis, mengeja, berbicara, dan membaca, akan sulit membedakan huruf-huruf di atas sehingga akan kesulitan menemukan tempat duduknya di pesawat.</p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-75543956678794867342023-04-10T14:24:00.000+07:002023-04-11T07:02:26.802+07:00DON'T DO USELESS THINGS!<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTxLslptffrR6vTrmCvl-uZbvGu-bVKieyTQs6NW9TYiK9YX_qr5Nu_ZIlFuqljNeYBjB9C3wQLGvthq2ep8ftQf9qj-F33ZUByVV6CCA-ZG6r7h9d_izgVc2mCvRDQL90Zc10Ip-y4sS22FnL0aIBmvmjdlvNkiTax7s7hIJCzEfHF8rUu0c21ODq/s1400/Screenshot%20from%202023-04-03%2016-11-04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1060" data-original-width="1400" height="484" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTxLslptffrR6vTrmCvl-uZbvGu-bVKieyTQs6NW9TYiK9YX_qr5Nu_ZIlFuqljNeYBjB9C3wQLGvthq2ep8ftQf9qj-F33ZUByVV6CCA-ZG6r7h9d_izgVc2mCvRDQL90Zc10Ip-y4sS22FnL0aIBmvmjdlvNkiTax7s7hIJCzEfHF8rUu0c21ODq/w640-h484/Screenshot%20from%202023-04-03%2016-11-04.png" width="640" /></a></div><br /> <p></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-46089894758940690852023-03-31T14:13:00.003+07:002023-03-31T15:16:30.622+07:00Research Plan 2023Seperti biasa, bulan April adalah tahun barunya jepang (Fiscal year、年度). Satu tahun (akademik, fiskal, kerja, dll. kecuali pajak) dihitung per 1 April dan berakhir 31 Maret. Jadi kalau bisa, pas hidup di Jepang, lahir tanggal 1 April, meninggal tanggal 31 Maret. Kenapa begitu? Kalau lahir 20 April, anda tidak bisa mengikuti sekolah (SD, SMP, SMA) tahun itu juga kalau belum umurnya. Misalnya umur minimal SD adalah 6 tahun per 1 April. Kalau lahir 20 April berarti nunggu tahun depannya. Begitu juga beasiswa, kerja, dll, hampir semua dimulai per 1 April. <div><br /></div><div>Singkat saja, berikut adalah rencana penelitian saya satu tahun mendatang. Tahun ini saya akan fokus mengembangkan sistem multilingual <i>speech emotion recognition (SER) </i>dengan riset tambahan tentang <i>anomaly detection (vibration and sound)</i> dan melanjutkan riset sebelumnya tentang <i>text-independent speech emotion recognition</i>. Semoga semua luaran tahun ini bisa tercapai, alih-alih bisa melebihi luaran yang diharapkan.</div><div><br /></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRA0OTNgc9Kd50QV2SRJq6_CqJ6UC4aDD4Cios75DlcpBJrNpSNS64sWXnbZuRISf_5NruM9E8FGH47ugs3vIhARGDxJo0aKpIUx-VIOn8JV-R38slgNz442c5_DTC-0BH8Gf59NMbMVB9y_hLE-6TGmPV4TpvPUx1gAx-KCr7zy5-taTb6R80F5aZ/s2106/riset_2023.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2106" data-original-width="1394" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRA0OTNgc9Kd50QV2SRJq6_CqJ6UC4aDD4Cios75DlcpBJrNpSNS64sWXnbZuRISf_5NruM9E8FGH47ugs3vIhARGDxJo0aKpIUx-VIOn8JV-R38slgNz442c5_DTC-0BH8Gf59NMbMVB9y_hLE-6TGmPV4TpvPUx1gAx-KCr7zy5-taTb6R80F5aZ/w424-h640/riset_2023.jpg" width="424" /></a></div><br /><div><br /></div>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-29686039065926679392023-03-14T07:57:00.000+07:002023-03-14T07:57:07.602+07:00Kopi dan Produktifitas<p> Dalam sebuat Twitter feed, seorang user berkicau?</p><blockquote><p>Adakah tool untuk meningkatkan produktivitas selain dengan minum kopi?</p></blockquote><p>Ada banyak jawaban dari kicauan itu. Ada yang menjawab dengan minuman lain kesukaannya, jus buah. Ada yang menyarankan musik klasik. Ada juga yang menyarankan musik khusus yang dibuat untuk menemani kerja (khususnya programming, <a href="https://musicforprogramming.net/latest/">https://musicforprogramming.net/latest/</a>). Saya baca-baca jawabannya lainnya, tidak ada yang masuk (untuk saya).</p><p>Saya pernah mencoba bekerja sambil mendengarkan musik (seperti musik programming di atas), dan kadang berhasil. Sebagai seorang muslim, saya juga mencoba bekerja sambil mendengarkan tilawah, dan kadang berhasil. Namun, sampai sekarang, saya belum menemukan tool lain yang bisa meningkatkan produktivitas (yakni: fokus, membuat kerja jadi selesai, efektif, dan efisien) seampuh kopi.</p><p>Khusus untuk tilawah, permasalahan utama ada pada keistiqomahan. Untuk minum kopi, saya otomatis menyambar gelas di disamping saya tapi tidak otomatis memutar tilawah padahal saya membutuhkannya. Qori favorit saya: Ali Jaber, Salaah Ba'uthman, dan Abdulallah Al-Mathrood. Suara tilawah menurut saya lebih mirip musik klasik (dari sisi ke efek gelombang otak) daripada <i>music for programming</i> di atas. <a href="https://twitter.com/i/status/1627592881040158722" target="_blank">Tilawah dipercaya meningkatkan laju pertumbuhan tanaman</a>. Senada dengan musik klasik dan tilawah, suara juga dapat dimodifikasi untuk menstimuli gelombang yang bisa mentrigger gelombak otak tertentu via brainwave synchronization. Ketiganya belum dapat menggantikan kedudukan kopi untuk meningkatkan produktivitas. Kalau mau dibuat variasi, Kopi dan Tilawah adalah perpaduan paling sempurna seperti yang dikampanyekan <a href="https://twitter.com/NuhSaunders" target="_blank">Nuh Saunders</a>. </p><p>Kembali ke pertanyaan yang mirip dengan pertanyaan user Twitter di atas: adakah tool yang bisa meningkatkan produktivitas seampuh kopi? Tidak ada. Kalau efektivitasnya di bawah kopi, mungkin ada. Tapi buat apa...? Kalau ada tool yang lebih efektif, pastinya pilih yang lebih efektif, kecuali bosan.<br /></p><p>Sediakan kopi untuk meningkatkan kinerja anda dan teman-teman anda.</p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-144086263790781452023-03-10T11:37:00.002+07:002023-03-10T11:37:55.697+07:00Antara Tukang Cuci Piring dan Editor Jurnal<p>Alkisah. Seorang teman bercerita, dia mendapat dua pilihan pekerjaan sampingan. Pertama sebagai pencuci piring. Kedua sebagai editor jurnal. Kerena bimbang untuk memilih salah satu diantara dua pekerjaan tersebut, beliau meminta pertimbangan istrinya. Berikut diskusi mereka.<br /></p><p>Istrinya bertanya, </p><blockquote><p>"Berapa waktu yang dibutuhkan untuk mereview satu jurnal?" </p></blockquote><p>Sang suami menjawab, </p><blockquote><p>"Kira-kira empat jam". </p></blockquote><p>Istri melanjutkan, </p><blockquote><p>"Berapa bayaran review dan mengedit satu jurnal itu?"</p></blockquote><p>Suami menjawab, <br /></p><blockquote><p>"Seratus dua puluh lima ribu rupiah". </p></blockquote><p>Istri bertanya lagi, </p><blockquote><p>"Berapa bayaran cuci piring?" <br /></p></blockquote><p>Suami menjawab:<br /></p><blockquote><p>"1000 yen jam per jam".</p></blockquote><p>Akhirnya si istri mengakhiri diskusi dengan solusinya.</p><blockquote><p>"Ya udah, kamu ambil kerjaan cuci piring saja, kamu sedekahkan separo dari bayaran cuci piringmu ke masjid di Indonesia, itu jauh lebih bermanfaat dari menjadi bekerja paruh waktu sebagai editor jurnal."<br /></p></blockquote>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-17962410514314307202023-03-08T08:41:00.020+07:002023-03-15T09:29:46.430+07:00Dari Narita, Cikarang, Jakarta, Solo, dan Madiun<p>Sebuah cerita dari perjalanan selama lima hari saat pulang ke Indonesia (Januari 2013).<br /><br />Berangkat dari Kameyama-shi, selasa pagi pukul 04.30 JST, saya di jemput oleh Kokubu-san, kemudian kami ke rumah sachou (Pak Direktur) untuk menjemput sachou dan dilanjutkan ke Tsu Port, Ibukota propinsi Mie di Jepang. Kapal yang membawa kami dari Tsu Seaport ke Central Japan Airport, Chubu, berangkat tepat pukul 6.00. Selama kurang lebih sejam berada di kapal cepat, akhirnya kami mencapai Chubu airport.<br /><br />Di Chubu air port, tiga moda transportasi disatukan: udara, laut dan darat. Begitu praktis dan efisiennya kehidupan di Jepang. Semuanya di desain untuk memudahkan hidup, bukan mempersusahnya. Inilah realiasi pajak yang saya bayar tiap bulannya di Negeri ini. Pemerintah (Jepang) pun melaksanakan tugasnya (memudahkan hidup rakyat) dengan cukup baik.<br /><br />Dari Chubu, kami berangkat naik pesawat ke Narita sekitar pukul 8.30, dengan waktu perjalanan sekitar 40 menit. Sebelum jam 10 kami sudah mendarat di Narita, Tokyo. Dari terminal domestik Narita, kami oper (Jepang: norikae) dengan shuttle bis bandara menuju terminal 1, terminal international yang akan membawa kami ke Indonesia.<br /><br />Jika pergi dari Jepang ke Indonesia, pilihan terbaik memang menggunakan Garuda, tanpa bermaksud promosi. Pengurusan visa (untuk warga negara asing seperti Jepang) bisa dilakukan setelah check in, sehingga kita tidak perlu mengurus visa on arrival ketika datang di Indonesia. Pesawat Garuda membawa kami meninggalkan Tokyo pukul 12.50 waktu setempat, dan kami tiba di Jakarta pukul 18.30 waktu setempat. Perjalanan ditempuh selama 6 jam termasuk perbedaan waktu antara Narita - Tokyo.<br /><br />Satu hal agar kita tidak rugi selama naik pesawat adalah dengan memaksimalkan fasilitas yang ditawarkan pesawat. Tiga film saya tonton dalam rentang beda waktu 6 jam. Namun fasilitas lain sepertinya Garuda kalah dengan maskapai lain, seperti Korean Air. Dengan harga tiket yang tidak jauh beda, Korean Air menawarkan fasilitas lebih (per tahun 2013).</p><p>Pertama tujuan kami adalah Cikarang (setelah mendarat di Sukarno-Hatta AP), di sana kami tinggal selama tiga hari sebelum bertolak ke Madiun via Solo (Adi Sumarno AP). Dari Solo ke Madiun, dari Madiun ke Solo lagi untuk menemui LPK (lembaga pelatihan kerja), milik orang yang memperkenalkan diri sebagai seorang yang berdarah biru, di dekat stadion Manahan. Kemudian, kami balik ke Jakarta untuk ke Narita. Perjalanan lima hari yang melelahkan untuk mengobati kerinduan kepada orang tua dan negeri tercinta.<br /></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-2082197668771941282023-02-21T15:00:00.008+07:002024-01-11T07:19:33.472+07:00Multi-device PCs with single keyboard and mouseIn today's digital age, it's common for people to use multiple devices for their work or personal use. Whether it's for multitasking or switching between devices, using multiple keyboards and mice can be a frustrating and inefficient experience. Fortunately, there's a solution to this problem: using a single keyboard and mouse for multiple PCs. This setup not only saves desk space but also improves productivity and reduces clutter. In this blog post, we'll explore the importance of using a single keyboard and mouse for multiple PCs, the benefits it offers, and how to set up this configuration for optimal performance. So, let's dive in and learn why using a single keyboard and mouse is a game-changer for those who use multiple devices! <div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXmnuVPqFejutGGBrGe5nVRMZhW52dqzQwDnk0_ErGBZ3ESHAvhF26W-53PQJAk-Z1Wax8xqGYJcgH4m0WXm8M1e4h729BigEEFccZgL60wzT9M8NEC-MnZ0qvvrjheyQWvprGi3RCu-qFeXz_YZqXMi7ux3JEWJujfDioFwROq8vCsNi67m2DYKiN/s4897/km7321.png" style="margin-left: auto; margin-right: auto;"><img alt="Dell KM7321" border="0" data-original-height="3409" data-original-width="4897" height="446" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXmnuVPqFejutGGBrGe5nVRMZhW52dqzQwDnk0_ErGBZ3ESHAvhF26W-53PQJAk-Z1Wax8xqGYJcgH4m0WXm8M1e4h729BigEEFccZgL60wzT9M8NEC-MnZ0qvvrjheyQWvprGi3RCu-qFeXz_YZqXMi7ux3JEWJujfDioFwROq8vCsNi67m2DYKiN/w640-h446/km7321.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Dell KM7321 multi-devices keyboard and mouse, as advertised on Dell's web. This keyboard and mouse can connect up to three PCs; one PC with a Bluetooth dongle and two PCs with embedded Bluetooth or additional Bluetooth dongles.</td></tr></tbody></table><br /><div><br /></div><p style="text-align: left;">PC setup </p><p style="text-align: left;">Here is my setup using three PCs (two desktops and one laptop).</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJnq23hmxoefSACDp-ybTjHXGQ34zVgDqNrKuqHhMUdhPqk2wSrOKXIhXMT8Ss9QtCGMliDMVMoQVlI46tS-XMetMcunNh8DobbiWkvjIt_CRDznnf6OT2D_3cLYObs89OdVaKDBk014tgL5r8SBQTS5LKQky_Gz7Wfvyg4BcNoxkJwj9i3hZS4iM5/s913/multi-devices.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="398" data-original-width="913" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJnq23hmxoefSACDp-ybTjHXGQ34zVgDqNrKuqHhMUdhPqk2wSrOKXIhXMT8Ss9QtCGMliDMVMoQVlI46tS-XMetMcunNh8DobbiWkvjIt_CRDznnf6OT2D_3cLYObs89OdVaKDBk014tgL5r8SBQTS5LKQky_Gz7Wfvyg4BcNoxkJwj9i3hZS4iM5/w640-h278/multi-devices.png" width="640" /></a></div><br /><p style="text-align: left;"><br /></p><div>Keyboard + Mouse: Dell KM7321W (KM7321WYG) </div><div>Technology: Bluetooth (universal pairing receiver)</div><div><br /></div><div>I mainly used two PCs as follows (with a laptop as an optional third device). It also works for three PCs; however, since the third is a laptop on a different table, it will make my work more complicated than using two PCs. </div><div><br /></div><div>PC1: Iiyama (Dell Bluetooth dongle) </div><div>I set the universal pairing dongle in this PC Iiyama. The OS is Ubuntu 20.04. Other hardware may not directly impact the performance, but I used the following; 95 GB RAM, RTX3090 (full four monitors), with i7-10900 CPU. Should work on other hardware too,</div><div><br /></div><div>PC2: HP Omen (Embedded Bluetooth) </div><div><br /></div><div>The second PC is the HP Omen 30 L (2021). GPU is RTX 3090, 64GB RAM, and Ubuntu 20.04 as the OS. I intended to use this PC as a computing unit, while the first one, PC Iiyama, for all tasks (paper writing, computation, etc.). For bigger computation, I used another PC with double RTX 3090.
Result
There is no software configuration needed. The only problem (previously) is to connect the keyboard to the second PC. For connecting the mouse, both PC 1 and PC 2 can connect smoothly. To connect the keyboard, we need to input six characters shown when pairing to the PC (shown in the PC). Since it was a keyboard, I didn't understand how to input these digits (like a smartphone or tablet). I tried it on Windows, and it shows a similar requirement (asking to enter six digits for the keyboard). I tried to push the number shown on the PC via the keyboard button (without knowing the pressed digits were correct) and then pressed enter. Whoala, the keyboard is now connected to the second PC. I tried similar things on Ubuntu, and it works. Finally, the image below is now my working workstation (two desktops, both the first and second PC are not shown since it is hidden under my table, only the monitors are shown).</div><div><br /></div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqDvejtvKqYKkUqq7dfrmnUbGQ76JnQp2-kvbl3k9Djmw26nQHb2dVZXhDSJZzM_vLRlinCVc3_OoOf4ZGxSG50OkIc9big4ORjboJiLJhYPq2Xs4i2TdQ3cy2Kj5d3CIK8nFAkZKCMwjZ2xZY-254ZXBPPmtMSwluJF6qFsXhQBOl1vauqZZkGSum/s2016/332048566_1653725941729887_5945379603890673983_n.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="954" data-original-width="2016" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqDvejtvKqYKkUqq7dfrmnUbGQ76JnQp2-kvbl3k9Djmw26nQHb2dVZXhDSJZzM_vLRlinCVc3_OoOf4ZGxSG50OkIc9big4ORjboJiLJhYPq2Xs4i2TdQ3cy2Kj5d3CIK8nFAkZKCMwjZ2xZY-254ZXBPPmtMSwluJF6qFsXhQBOl1vauqZZkGSum/w640-h302/332048566_1653725941729887_5945379603890673983_n.jpg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">A single keyboard to rule all three PCs.</td></tr></tbody></table><br /><div><div>PC3: IIyama 17" (Optional, just to test, embedded/buil-in bluetooth)</div><div>The third PC is a laptop with Windows 10. So, besides multi-device, this setup can also work in multi-OS. Since it is a hardware-based, different approach from software-based like Synergy, it is expected to work on any OS as long as the hardware supports Bluetooth.</div><div><br /></div><div>Note, as advertised, the mouse and keyboard support Swift pairing (without inputting the digits with a close distance between both devices). But, as I reported, this feature fails on my PCs. It may be too far. Being able to connect both devices (keyboard and second/third PC) via a physical button is enough to make the device work as intended.</div></div><div><br /></div><div>Update after a week of use</div><div><br /></div><div>Adjusting the monitor position is important. I used three monitors for the main PC (PC IIyama) and one monitor for the second PC (HP Omen, mainly for coding).</div><div><br /></div><div>Since I have an additional mouse (the old one), I just need to change the keyboard only for two devices. It is smoother than changing both the keyboard and mouse.</div><div><br /></div><div>It is also more convenient to use a single keyboard and mouse than using "ssh" for remote work. The use of GUI-based remote control like TeamViewer has been banned in my office. So, this solution is worth trying.</div><div><br /></div><div>Does it work with an external Bluetooth dongle?</div><div><strike>I haven't tried it yet (still ordering a Buffalo Bluetooth dongle). I will report here once a test has been performed. </strike> Yes. It does work with external Bluetooth. See the manual page for details.</div><div><br /></div><div>Reference: </div><div> [1] https://www.dell.com/support/home/en-us/product-support/product/dell-premier-multi-device-wir-kybrd-mse-km7321w/docs</div>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-77315434582673332432023-01-10T11:32:00.005+07:002023-03-08T10:25:16.044+07:00Dual Afiliasi<p>Salah satu cita-cita saya yang belum tercapai adalah dual afiliasi, bekerja di dua institusi dan memberi manfaat untuk keduanya dengan mengisi kekurangan satu insitusi dengan kelebihan institusi lainnya, begitu pula sebaliknya. Contoh terbaik untuk kasus ini adalah Bjorn Schuller (Imperial College dan Audeering), Yan Lecun (Facebook dan New York University), Junichi Tsujii (AIST dan Manchester University), dan Junichi Yamagishi (NII dan Edinburg University). <br /></p><p>Contoh dari manfaat dual afiliasi adalah pada riset dan publikasi akademik. Biaya publikasi akan tertutupi oleh institusi yang secara finansial lebih stabil. Keuntungan untuk instituti yang secara finansial lebih stabil adalah pada kolaborasi. Contohnya pada institusi privat (Swasta), dimana butuh usaha ekstra untuk merekrut peneliti dan kolaborator. Sebaliknya, hal tersebut mudah dilakukan di universitas. Institusi privat tidak perlu mengeluarkan waktu dan biaya ekstra untuk proyek mereka.</p><p>Manfaat utama ada pada siklus teori dan praktek. Dosen (seperti Lecun) yang bekerja di sektor swasta secara dual afiliasi akan dengan mudah menangkap permasalahan nyata (praktek) di lapangan/industri, alih-alih permasalah teoritik di buku teks. Mahasiswa dari dosen yang bersangkutan juga akan memecahkan permasalahan nyata, the real problem, bukan sebatas permasalahan yang ada di buku teks. Permasalahan (soal-soal) di buku teks tetap penting untuk mengasah teori atau konsep dasar dan kerangka berpikir dalam menyelesaikan permasalahan nyata.</p><p></p><h4 style="text-align: left;">Double Universitas</h4><div>Selain dual afiliasi universitas dan industri, dual afiliasi bisa juga dilakukan pada dua (atau lebih) kampus yang berbeda. Banyak dosen China yang mengambil dual afiliasi dengan universitas Jepang untuk memanfaatkan kebaikan dan kelebihan universitas Jepang (~2020). Dosen-dosen China tersebut tinggal di Jepang dan hanya pulang ke China ketika dibutuhkan saja. Dengan cara yang sama, banyak dosen-dosen Eropa bertebaran tidak di negaranya (sesama Uni Eropa) dengan memanfaatkan kelebihan-kelebihan kampus papan atas Uni Eropa untuk mendongkrak reputasi universitas Uni Eropa lainnya.</div><div><br /></div><h4 style="text-align: left;">Keterbatasan Untuk Dosen PNS</h4><p>Ada keterbatasan PNS (atau dosen yang berstatus sebagai PNS). Keterbatasan rangkap jabatann tersebut seperi yang didiskusikan di sini: <a href="ttps://www.hukumonline.com/klinik/a/hukumnya-rangkap-menjadi-asn-sekaligus-pegawai-swasta-lt5ed13c19b8117">https://www.hukumonline.com/klinik/a/hukumnya-rangkap-menjadi-asn-sekaligus-pegawai-swasta-lt5ed13c19b8117</a>. Diperlukan usaha ekstra untuk mewujudkan dual afiliasi sebagai dosen PNS dan praktisi di tempat lain (atau peneliti di institusi lain).<br /></p><p><br /></p><p>p.s.: Saat ini saya dual afiliasi, namun bukan sebagai pekerja tetap di salah satu instansinya. Cita-cita saya adalah menjadi staf tetap (long-term) di dua institusi, akademik dan universitas luar negeri atau industri/institusi riset.<br /></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-24638840264160371532023-01-04T08:20:00.003+07:002023-01-13T11:01:58.535+07:00Tools for Academic Writing in 2023<p>When writing a scientific paper, I use several tools below to boost and speed up my writing process. Hence, I only need two weeks to a month to complete the first version of my manuscript (after the experiment has been conducted). Two tools are paid: Copilot and Grammarly. Before going down to the list below, you may also be interested in<a href="http://bagustris.blogspot.com/2020/07/resources-for-academic-writing-word.html" target="_blank"> my resources for academic writing - word concordance</a> [1]. For last year's tool (2022), specializing on both research and paper writing instead of paper writing only, you can check it <a href="https://bagustris.blogspot.com/2023/01/tools-i-used-for-accelerating-science.html" target="_blank">here</a> [2].<br /></p><p></p><ol style="text-align: left;"><li><a href="http://www.mendeley.com" target="_blank">Mendeley</a> (the old desktop version, not the new reference manager, to create a BIB file automatically)</li><li><a href="https://github.com/znck/grammarly" target="_blank">Grammarly</a> (vscode plugin)</li><li><a href="https://github.com/James-Yu/LaTeX-Workshop" target="_blank">Latex Workshop</a> (vscode plugin)</li><li><a href="https://github.com/features/copilot" target="_blank">Copilot</a> (vscode plugin)</li><li><a href="https://chat.openai.com/chat" target="_blank">ChatGPT</a> (to ask questions)</li></ol><div>By using these tools, I DON'T need to:</div><div><ul style="text-align: left;"><li>Create bibliography manually</li><li>Sometimes, write all sentences in paragraphs since Copilot will do it.</li><li>Check the grammar manually.</li><li>Create Table, Figure, and Equation manually in Latex (thanks to Latex Workshop).</li></ul></div><div>Other tools (unexplored well, in progress for adaptation)</div><div><ol style="text-align: left;"><li>https://www.explainpaper.com (tool to explain any hard-to-understand terms/sentences in a paper)</li><li>https://elicit.org/ (like ChatGPT, but with reference)</li><li>LTeX – LanguageTool grammar/spell checking (alternative to Grammarly, free)</li></ol><div><br /></div></div><div>Reference</div><div>[1] http://bagustris.blogspot.com/2020/07/resources-for-academic-writing-word.html</div><div>[2] <span><span class="w4txWc oJeWuf" id="i8" role="region"><span class="MUhG4e OGjyyf" data-blogurl="https://bagustris.blogspot.com/">https://bagustris.blogspot.com/2023/01/tools-i-used-for-accelerating-science.html</span></span></span> </div><p></p>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-35764487623802025912022-12-27T10:51:00.014+07:002023-01-06T14:49:00.485+07:00Mengikuti Sekolah Mengemudi Di Jepang<p>Tulisan ini adalah catatan pengalaman saya mengikuti sekolah mengemudi di Jepang di awal tahun 2022.</p><h4 style="text-align: left;">Kenapa driving school?</h4><p>Ada tiga jalur untuk mendapatkan SIM di Jepang, yakni:</p><p>1. Jalur Sekolah (自動車学校, jidousha gakko)</p><p>2. Jalur Konversi (外免切替, gaimen kirikae)</p><p>3. Jalur Umum (普通一種一般試験, futsu isshu ippan shiken)</p><p>Dari ketiga jalur di atas, kenapa saya memilih jalur driving school?</p><p>1. Saya belum pernah 'pegang' mobil secara formal dan tidak punya SIM A untuk dikonversi.</p><p>2. Meski saya bisa saja belajar sendiri kemudian lewat jalur formal, namun waktunya akan sangat lama (1-2 tahun) kalau pakai jalur umum. Waktu tempuh ini juga berlaku untuk mereka yang sudah bisa (bahkan pandai menyetir).</p><p>3. Jalur driving school adalah yang paling cepat meski paling mahal.</p><p>Oya, ada dua tipe driving school di Jepang: driving school yang punya lisensi untuk tes tulis 50 soal dan praktek, dan driving shool yang tidak punya lisensi tersebut. Saya memilih driving school tipe pertama.</p><h4 style="text-align: left;">Pendaftaran</h4><p>Satu-satunya kelemahan jalur driving school adalah biaya pendaftaran yang mahal, yakni sekitar 336,000 yen. Namun, seperti telah saya sampaikan di atas, jalur ini adalah yang tercepat. Saya hanya butuh sekitar dua bulan dari hari pertama les nyetir sampai dengan mendapatkan SIM resmi (bukan SIM belajar atau kari menkyou). </p><p>Untuk info kursus mengemudi yang saya ikuti adalah sebagai berikut.</p><p>Nama : Tsuchiura Driving School (Tsuchiura Jidouka Gakkou)</p><p>Web:<a href="https://tsuchikyo.menkira.jp/" target="_blank"> https://tsuchikyo.menkira.jp/</a></p><p>Alamat: </p><p>〒300-0843 茨城県土浦市中村南 4-1-20</p><p>TEL 029-841-0577</p><p>Tips saat mendaftar: Jika anda bisa bahasa Jepang sehari-hari, jangan bilang kalau tidak bisa bahasa Jepang. Cukup bilang 日本語は大丈夫です。</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc-dmy9rECjm73LyQdzFZiHoXQXIurUz-IMolAnd0F1InzhWXzIHpwXBRR5-VdEp2EAD8BvQ8qvgoptHuAcNjmamhvKkiHDJnHpNivIYk8QW-WGI9NMt_8QaDdHkfBg-W5gNyNTx6oLvoHDgsxYxH78nY8tCvFhikrdYUNY-hM7PmyLpZ-CvmLgCr-/s880/car-tsuchiura.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="585" data-original-width="880" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc-dmy9rECjm73LyQdzFZiHoXQXIurUz-IMolAnd0F1InzhWXzIHpwXBRR5-VdEp2EAD8BvQ8qvgoptHuAcNjmamhvKkiHDJnHpNivIYk8QW-WGI9NMt_8QaDdHkfBg-W5gNyNTx6oLvoHDgsxYxH78nY8tCvFhikrdYUNY-hM7PmyLpZ-CvmLgCr-/w640-h426/car-tsuchiura.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Gambar 1. Mobil yang digunakan untuk latihan (Toyota)</td></tr></tbody></table><br /><p><br /></p><h4 style="text-align: left;">Alur </h4><p>Ada empat tahapan atau langkah untuk mendapatkan SIM untuk semua jalur di atas.</p><p>1. Tes Praktek I untuk Kari Menkyou</p><p>2. Tes Tulis 50 soal</p><p>3. Tes Praktek II</p><p>4. Tes Tulis 100 soal</p><p>Jika keempat langkah di atas lulus, maka SIM bisa didapatkan. Jika langkah 1-2 terpenuhi, maka SIM belajar (kari menkyou) bisa didapatkan. Jika ada satu saja langkah di atas yang gagal, maka SIM tidak bisa didapatkan. Untuk mengulang setiap langkah ada biaya tambahan, untuk semua jalur. Kasus saya gagal sekali pada tes 50 soal dan mengulang dan membayar biaya test tsb (1700 yen untuk sekali tes).</p><h4 style="text-align: left;">Kelas</h4><p>Hari Pertama</p><p>Hari pertama ini bisa dibilang fullday. Jam pertama dimulai jam 9:50 dan berakhir jam 17:50. Istirahat dua kali, jam 11:15-11:50 dan jam 12:50-13:30. Ada tiga kelas (学会, gakkai)sekaligus, yakni kelas 1, 6, dan 9. Oya, total ada 26 kelas yang dibagi menjadi dua periode (sebelum dan setelah kari menkyou/SIM belajar). Di kelas pertama tadi dikenalkan pengertian kendaran (車, kuruma) yang meliputi mobil (自動車), sepeda (自転車), dan sepeda motor (モトバイク). Poin-poin penting kelas 1 meliputi: seat belt, child seat, driving license, dan surat kelayakan kendaraan (車検). Poin-poin penting kelas 6 membahas banyak tentang perempatan (tata cara belok, berhenti, lurus). Kelas 9 lebih banyak membahas tentang pejalan kali, zebra cross, mengemudi di samping pejalan kali, sepeda, kursi roda dan sejenisnya. Pada hari pertama ini ada dua (jam) praktek. Praktek pertama dengan simulator meliputi: persiapan sebelum mengemudi (cek depan dan belakang), menyetel kursi, menstarter mobil, memindahkan handle dari P, ke R, N, D, S, B (sambil menginjak rem), belok kanan dan belok kiri (tangan dalam keadaan lurus untuk putaran setir > 180 derajat). Praktek kedua adalah dengan mobil asli setelah melalui simulator.<br /></p><p>Hari Kedua</p><p>Pada hari kedua ada dua kelas dan dua praktek. Kelas pertama adalah kelas 8 membahas tentang perempatan meliputi cara berpindah jalur, menyalip, dan belok kiri kanan. Praktek pertama di hari kedua ini (praktek ketiga secara total) adalah latihan belok (putaran) kanan, kebalikan dari hari pertama. Belok kanan dan kiri berbeda, putaran belok kanan lebih sedikit dari belok kiri. Kelas kedua yakni kelas 10 membahas tentang jenis-jenis SIM (ada tiga: kelas 1, kelas 2, SIM belajar), jenis-jenis SIM dari berat kendaraan dan pelanggaran lalu lintas beserta hukumannya. Setiap melanggar, selain tindakan langsung (tilang) berupa uang, pelanggar akan dikenakan poin. Jika poin tersebut sudah mencapai batas, SIM akan dicabut baik sementara atau permanen. Pada praktek kedua saya berlatih belok kanan dan kiri (sasetsu dan usasetsu). Praktek ini juga meliputi implementasi kelas 8 yakni cara berpindah jalur: lihat room mirror, side mirror, nyalakan sein, hitung tiga detik, tengok kanan, pindah jalur. Praktek kedua ini sangat penting untuk membiasakan menyetir.</p><p>Hari ketiga</p><p>Hari ketiga mirip dengan hari sebelumnya: dua kelas dan dua praktek. Kelas pertama dimulai dari buku "Rules of the Road" hal 114 berkaitan dengan menyalip, kapan dilarang menyalip, di mana dilarang menyalip dan sejenisnya. Contohnya larangan menyalip adalah ketika mobil di depan kita juga mau menyalip. Contoh tempat dilarang menyalip adalah tanjakan. Kelas kedua berkaitan dengan mobil-mobil emergensi: ambulans, pemadam kebakaran, dan polisi (untuk mengutamakan mobil tersebut). Praktek pertama naik tanjakan dan pindah lajur kanan (berhenti sejenak, rem tangan, gas pelan, lepas rem tangan, bel, reteng kanan, D-->S, turun sambil injak rem pelan-pelan, berhenti, S --> D. Praktek kedua di tikungan S dan J. Poin penting praktek kedua ini adalah injakan rem dan kapan memutar dan mengembalikan handle dengan melihat jalan.</p><p>Hari keempat</p><p>Skema hari keempat sama dengan hari sebelumnya, dua teori (kelas) dan dua praktek. Kelas pertama berkaitan lampu lalu lintas (merah, kuning, hijau dengan empasis kuning harus berhenti pada dasarnya, kecuali sudah melewati garis putih). Lamu lalu lintas di Jepang berbeda dengan Indonesia, meski hijau tidak serta merta jalan, menunggu mobil dari arah lawan, jika kosong baru bisa jalan. Kelas kedua berkaitan dengan rambu-rambu lalu lintas (secara garis besar dibagi dua, rambu di pinggir jalan dan rambu di permukaan jalan). Praktek pertama dan kedua sama, course seperti gambar di bawah. Bedanya, praktek pertama mbak instrukturnya gaul (pernah tinggal di Jakarta tujuh tahun), sedangkan praktek kedua mbak instrukturnya judes.</p><p>Hari keenam</p><p>Hari keenam hanya dua praktek. Dua-duanya sama, praktek kedua mengulang praktek pertama. Praktek ini adalah gladi resik untuk praktek I. Rutenya seperti gambar di bawah.</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe9zOJwOmR3-gHQCuLxrxLeLnL_Nbo7GMlfxGAQw7qvUfTrgdM_SML_aUY-p5HQcxwZPjom39wlgEVfwNsUR04yPf_3TTPMyf2ndxnLJx0BcH9rX3PK00wYCEVlj3GZedjSgW8zdthWDK7wx0K9uibHwQtD44v6ptVvAzhnGoVr8ih-ytXlf3aktTH/s1215/Tsuchiura_driving.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="655" data-original-width="1215" height="346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe9zOJwOmR3-gHQCuLxrxLeLnL_Nbo7GMlfxGAQw7qvUfTrgdM_SML_aUY-p5HQcxwZPjom39wlgEVfwNsUR04yPf_3TTPMyf2ndxnLJx0BcH9rX3PK00wYCEVlj3GZedjSgW8zdthWDK7wx0K9uibHwQtD44v6ptVvAzhnGoVr8ih-ytXlf3aktTH/w640-h346/Tsuchiura_driving.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Gambar 2. Rute Latihan / Tes Praktek I</td></tr></tbody></table><br /><p><br /></p><h3>Tes Tulis 50 Soal (Hari ketujuh)</h3><p>Hari ketujuh adalah test untuk step 1. Tes ini merupakan test praktek dengan course C sesuai gambar. Untuk mengambil tes ini harus lulus pre-test online 1, 2, dan 3. Masing-masing test online untuk step 1 berisi 50 soal benar atau salah. Untuk lulus harus memiliki skor (benar) minimal 45. Ada trik khusus untuk test online ini. Setelah test akan muncul review atas jawaban benar dan salah. Highlight semua pertanyaan dan jawaban kemudian print di browser dalam bentuk pdf. Ketika mengulang lagi, tinggal melihat jawaban yang benar. Meski pertanyaannya acak, ada banyak pertanyaan yang sama untuk tiap pre-test tersebut sehingga file pdf sebelumnya sangat membantu untuk mencari jawaban yang benar. Dari test praktek saya mendapat masukan untuk menginjak rem lebih halus dan tidak mendadak. Setelah test praktek adalah test tulis. Meski saya sudah lulus tiga pre-test online di test tulis ini saya tidak lulus. Saya gagal di tes pertama 50 soal untuk mendapatkan kari menkyou. Walhasil saya harus mengulang dan membayar pendaftaran 1700 yen. Jadwal short-term plan saya juga langsung berubah menjadi basic plan.</p><p><br /></p><p>Hari ke delapan dan seterusnya lupa tidak tercatat, tapi catatan berikut di bawah ini cukup bermanfaat.</p><p><br /></p><h3 style="text-align: left;">Tes Praktek I</h3><div>Tes praktek I ini secara umum mudah karena hanya di lintasan di dalam driving school (tidak keluar ke jalan raya). Beberapa hal yang perlu diperhatikan adalah saat sebelum mengemudi (cek spion tengah, side mirror) kemudian toleh kanan kiri dan start. Minimal kecepatan pada jalan lurus adalah 40 km,/jam sekali saja. Kecepatan pada saat belok maksimal 15 km/jam. Belokan S juga diujikan pada tes praktek I ini.</div><div><br /></div><h3 style="text-align: left;">Mikiwame</h3><p style="text-align: left;">Mikiwame adalah semacam gladi resik untuk tes praktek (II). Jadi materinya hampir sama dengan test praktek II. Pada mikiwame ini saya mengendarai mobil di rute yang akan dijadikan test, termasuk juga mengendarai mobil di arena di dalam driving school. Beberapa teknik yang di-teskan antara lain houkohenkan (putar balik) dan parkir. Pada hari tes, dua dari teknik tersebut akan dipilih salah satu secara acak.</p><h3 style="text-align: left;">Tes Praktek II</h3><p style="text-align: left;">Meski berhasil pada tes praktek II ini, ada banyak pelajaran yang bisa di ambil. Utamanya adalah untuk "mendahulukan yang mudah daripada yang sulit" (無理しないでください). Kasus pertama pelajaran tersebut ketika berada di perempatan untuk belok kanan. Di Jepang, belok kanan tidak bisa langsung meski lampunya hijau, jadi mobil harus maju pelan-pelan sampai di tengah perempatan menunggu mobil dari arah kiri kosong (atau panah kanan hijau menyala pada lampu lalu lintas). Karena mobil di depan saya maju, saya juga ikut maju di belakangnya. Di akhir test, instruktur mengatakan bahwa saya terlalu mempersulit diri. Baiknya, menunggu di belakang zebra cross, tidak perlu mengikuti mobil di depan ke tengah perempatan. Kasus kedua ketika putar balik (Gambar 2, bagian kiri atas), saya beberapa kali maju dan mundur untuk mengatur agar mobil pas di tengah (seperti parkir). Di akhir instruktur mengatakan, karena bukan parkir, kamu gak perlu bersusah payah mengatur mobil, intinya mobil bisa putar balik (mundur, belok kiri, dan belok kanan). Alhamdulillah meski agak susah saya lulus di tes praktek II ini.</p><h3 style="text-align: left;">Tes Tulis 100 soal di Mito: </h3><h1>LULUS!</h1><p>Ini adalah tes terakhir, bukan di driving school tapi di menkyou senta (Mito-shi). Alhamdulillah saya langsung lulus di tes pertama ini. Tipsnya banyak-banyak buku "Master of your driving in Japan" saja. Penantian kelulusan ini mirip-mirip ujian, menunggu nomor kita ada di layar monitor (lulus) atau tidak. Alhamdulillah nomor saya muncul di layar, langsung dapat SIM hari itu juga (setelah tes mata dan mengikuti arahan-arahan lainnya). Qodarullah, sehari setelah dapat SIM saya langsung dapat mobil. Alhamdulillah.</p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcNygLZCl81ZoOSTRRzSZjFX_vGtJcd8e6v98XJhChwsefm6kJVljgm9MaD_JzX9W_yXSNgmT0zD8liFPSwauDCPdUEgAxKHytSed32QPqu-8ZKjisG7GQchLRvipj7MF1grSIdtySwizVWuoSnJuMvph3oDoyCHCOgq16UnLI7BHEJJYgph4pghV9/s1631/Selection_010.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="860" data-original-width="1631" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcNygLZCl81ZoOSTRRzSZjFX_vGtJcd8e6v98XJhChwsefm6kJVljgm9MaD_JzX9W_yXSNgmT0zD8liFPSwauDCPdUEgAxKHytSed32QPqu-8ZKjisG7GQchLRvipj7MF1grSIdtySwizVWuoSnJuMvph3oDoyCHCOgq16UnLI7BHEJJYgph4pghV9/w640-h338/Selection_010.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Gambar 3. Nomor ujian saya, 162, muncul di layar menandakan kelulusan ujian SIM di Jepang</td></tr></tbody></table><br /><div><br /></div><div>P.S: Jika anda ingin mengikuti driving school di Tsuchiura Driving School, anda bisa memasukkan nama saya dan alamat saya untuk mendapatkan potongan biaya 7000 yen (referral). Silahkan email saya di (btatmaja[at]gmail[dot]com) untuk mendapatkan alamat saya.</div><div id="rikaichan-window" lang="ja" style="all: revert;"></div>bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.comtag:blogger.com,1999:blog-2700379026445832630.post-60387893878140310522022-11-25T08:12:00.001+07:002022-11-25T08:13:43.160+07:00Konversi Fail Stereo ke Mono Dari Direktori Berisi Banyak Fail SuaraSkrip berikut dapat merubah fail suara stereo ke mono dari suatu direktori (termasuk subdirektori di dalamnya) yang diberikan.
<br/>
Input: Direktori/folder <br/>
Output: Fail berakhiran "_mono" dengan direktori yang sama terhadap input (termasuk subdirektori)
<pre class="prettyprint">
#!/usr/bin/env python3
import os
import argparse
import glob
from pydub import AudioSegment
def stereo2mono(files):
"""Convert all files from stereo to mono.
Note: this would effectively also create a copy of files that were already in a mono format
Parameters
----------
files : iterable
Sequence of files
Example use:
```
$ python3 stereo2mono.py -f /path/to/audio/files/
```
Then you may remove the files that do not contain the '_mono' tag with:
$ find . -name "*-??.wav" -delete # for emovo
"""
for f in files:
print(f"Converting {f}")
# Load audio
sound = AudioSegment.from_wav(f)
# Convert to mono
sound = sound.set_channels(1)
# Save file
stem, ext = os.path.splitext(f)
sound.export(f'{stem}_mono{ext}', format='wav')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Convert stereo to mono')
parser.add_argument('-f', '--folder',
type=str, help='Path to wavfiles')
args = parser.parse_args()
files = glob.glob(args.folder + '**/*.wav', recursive=True)
stereo2mono(files)
</pre>
Contoh penggunaan <br/>
<pre># Konversi ke mono
python3 stereo2mono.py -f tensorflow_datasets/downloads/extracted/ZIP.emovo.zip/EMOVO/
# menghapus file yang bukan mono
$ pwd
/home/bagus/tensorflow_datasets/downloads/extracted/ZIP.emovo.zip/EMOVO/
$ find . -name "*-??.wav" -delete
</pre>
Referensi gist: <br/>
1. <a href="https://gist.github.com/bagustris/40b406d99820207bc804a020db169f7e" target="_blank">https://gist.github.com/bagustris/40b406d99820207bc804a020db169f7e</a>
bagustrishttp://www.blogger.com/profile/18146483246455521334noreply@blogger.com