{"id":469,"date":"2025-03-19T19:54:16","date_gmt":"2025-03-19T19:54:16","guid":{"rendered":"https:\/\/r.jander.me.uk\/?p=469"},"modified":"2025-03-19T19:58:48","modified_gmt":"2025-03-19T19:58:48","slug":"external-usb-audio-on-ev3-using-ev3dev","status":"publish","type":"post","link":"https:\/\/r.jander.me.uk\/index.php\/2025\/03\/19\/external-usb-audio-on-ev3-using-ev3dev\/","title":{"rendered":"External (USB) Audio on EV3 Using ev3dev"},"content":{"rendered":"\n<p>Recently, whilst working on my <a href=\"https:\/\/r.jander.me.uk\/index.php\/2023\/12\/09\/braill3-an-ev3-based-braille-bricks-reader\/\" data-type=\"post\" data-id=\"376\">Braille Reader<\/a> rebuild, I decided that it was time to investigate options for an external speaker to increase the volume, as the onboard speaker is rather quiet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bluetooth Speaker<\/h2>\n\n\n\n<p>I&#8217;d seen that other people had managed to  get Bluetooth speakers working with ev3dev and Pulseaudio, so since I had a BT speaker lying around I thought I&#8217;d give it a go. Unfortunately it wouldn&#8217;t connect. The EV3 would see it, pair, but any attempt to connect resulted in a Bluez error. It was an old speaker so I decided I&#8217;d get a new Anker (I&#8217;m a fan of their stuff) one, which would also see duty with my <a href=\"https:\/\/www.pippyg.com\/pipistrelleprev.html\">bat detector<\/a> as well. That also didn&#8217;t connect. I&#8217;m guessing that the EV3 wants to use a rather old protocol that neither of my speakers supported, which is a shame.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">USB Audio<\/h2>\n\n\n\n<p>Not one to give up on using an external speaker I wondered if USB audio would work instead. When I changed my phone, I ended up buying an Anker USB-C to 3.5mm headphone DAC:<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" data-id=\"470\" src=\"https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-1024x1024.jpg\" alt=\"\" class=\"wp-image-470\" srcset=\"https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-1024x1024.jpg 1024w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-300x300.jpg 300w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-150x150.jpg 150w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-768x768.jpg 768w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-1536x1536.jpg 1536w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-2048x2048.jpg 2048w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_181014491-edited-1200x1200.jpg 1200w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n<\/figure>\n\n\n\n<p>I did need to use a USB-A to USB-C adapter, but it worked. It worked really well, on the whole. Using USB alone didn&#8217;t require Pulseaudio to be installed once I&#8217;d set up the .asoundrc file in ~robot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>defaults.pcm.card 1\ndefaults.ctl.card 1<\/code><\/pre>\n\n\n\n<p>The downside to using .asoundrc is that if the USB adapter wasn&#8217;t plugged in, there&#8217;d be no output. So I decided I write a little audio configure function that could be called at the start of my program to detect if there were any additional audio outputs and present a menu of choices, defaulting to the current one in .asoundrc:<\/p>\n\n\n\n<figure class=\"wp-block-gallery aligncenter has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"805\" data-id=\"467\" src=\"https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-1024x805.jpg\" alt=\"\" class=\"wp-image-467\" srcset=\"https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-1024x805.jpg 1024w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-300x236.jpg 300w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-768x604.jpg 768w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-1536x1208.jpg 1536w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-2048x1610.jpg 2048w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_1823043142-1200x943.jpg 1200w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n<\/figure>\n\n\n\n<p>If only the onboard audio is available, no menu will be shown and it sets the .asoundrc to use device 0.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Issues<\/h2>\n\n\n\n<p>So that I didn&#8217;t need to use the USB-A to USB-C adapter I did buy a USB-A audio device:<\/p>\n\n\n\n<figure class=\"wp-block-gallery aligncenter has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" data-id=\"471\" src=\"https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-1024x1024.jpg\" alt=\"\" class=\"wp-image-471\" srcset=\"https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-1024x1024.jpg 1024w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-300x300.jpg 300w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-150x150.jpg 150w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-768x768.jpg 768w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-1536x1536.jpg 1536w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-2048x2048.jpg 2048w, https:\/\/r.jander.me.uk\/wp-content\/uploads\/2025\/03\/PXL_20250319_180951864-edited-1200x1200.jpg 1200w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/figure>\n<\/figure>\n\n\n\n<p>I wouldn&#8217;t suggest using that one. It&#8217;s very, very, quiet and the audio quality is poor. It glitches and, worst of all, it chops off the beginning of any sounds played to it which, given I want to use it for speech output, isn&#8217;t useful. The Anker unit is just so much better: louder, smoother, and plays the entire sound.<\/p>\n\n\n\n<p>The other issue I came across is that using the ev3.speaker.say(&#8230;) function would often crash. It appears that the EV3 isn&#8217;t powerful enough to manage sending USB data whilst generating speech via <em>espeak<\/em> and sending that on to <em>aplay<\/em>. My answer to that is to manage all that in my own code and temporarily write the speech output to the \/run\/user\/1000 <em>tmpfs<\/em> directory &#8211; that way it won&#8217;t damage the SD card:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    def Speak(self, text, filename=None):\n        if filename:\n            play = False\n        else:\n            filename = \"\/run\/user\/1000\/speech.wav\"\n            play = True\n\n        os.system(\n            \"espeak -a {} -v {} -s {} -p -w {} '{}'\".format(\n                self.speech&#91;'volume'],\n                self.speech&#91;'voice'],\n                self.speech&#91;'speed'],\n                self.speech&#91;'pitch'],\n                filename,\n                text\n            )\n        )\n\n        if play:\n            self.ev3.speaker.play_file(filename)<\/code><\/pre>\n\n\n\n<p>The code above accepts a filename as, for the Braille reader, I pre-generate some cached text prompts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Utils Code Library<\/h2>\n\n\n\n<p>I&#8217;ll blog separately, but I refactored all the code that was used to generate the device selection menu et al into its own package so that I could release that. Hopefully it&#8217;ll be useful to someone else.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently, whilst working on my Braille Reader rebuild, I decided that it was time to investigate options for an external speaker to increase the volume, as the onboard speaker is rather quiet. Bluetooth Speaker I&#8217;d seen that other people had managed to get Bluetooth speakers working with ev3dev and Pulseaudio, so since I had a &hellip; <a href=\"https:\/\/r.jander.me.uk\/index.php\/2025\/03\/19\/external-usb-audio-on-ev3-using-ev3dev\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;External (USB) Audio on EV3 Using ev3dev&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[62,37,26,34],"class_list":["post-469","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-audio","tag-ev3dev","tag-lego","tag-python"],"_links":{"self":[{"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/posts\/469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/comments?post=469"}],"version-history":[{"count":6,"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":477,"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/posts\/469\/revisions\/477"}],"wp:attachment":[{"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/media?parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/categories?post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/r.jander.me.uk\/index.php\/wp-json\/wp\/v2\/tags?post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}