{"id":307,"date":"2018-03-18T16:14:08","date_gmt":"2018-03-18T16:14:08","guid":{"rendered":"https:\/\/geekblog.febo.com\/wp\/?p=307"},"modified":"2018-03-18T19:18:06","modified_gmt":"2018-03-18T19:18:06","slug":"add-streaming-audio-to-op25-rpi-scanner","status":"publish","type":"post","link":"https:\/\/blog.febo.com\/?p=307","title":{"rendered":"Add streaming audio to OP25 RPi scanner"},"content":{"rendered":"<p>Thanks to <A HREF=\"https:\/\/github.com\/boatbod\/op25\">Graham Norbury<\/A>, here is how to set up a Raspberry Pi OP25 scanner to stream audio to an icecast or other streaming server.  I have updated my plug-and-play <code>op25-rpi.img<\/code> image at <A HREF=\"http:\/\/febo.com\/pages\/os_images\/\">http:\/\/febo.com\/os_images\/<\/A> to include this capability (look for the 2018-03-18_op25_rpi.zip or later-dated file).<\/p>\n<p>1.  Copy the following into a new file \/etc\/asound.conf on the Raspberry Pi (you&#8217;ll need to do this as root):<\/p>\n<p><code><br \/>\n# output device<br \/>\npcm.loopout {<br \/>\n  type dmix<br \/>\n  ipc_key 328211<br \/>\n  slave.pcm \"hw:Loopback,0,0\"<br \/>\n}<\/p>\n<p># input device<br \/>\npcm.loopin {<br \/>\n  type dsnoop<br \/>\n  ipc_key 686592<br \/>\n  slave.pcm \"hw:Loopback,1,0\"<br \/>\n}<\/p>\n<p># duplex plug device<br \/>\npcm.loop {<br \/>\n  type plug<br \/>\n  slave {<br \/>\n    pcm {<br \/>\n      type asym<br \/>\n      playback.pcm \"loopout\"<br \/>\n      capture.pcm \"loopin\"<br \/>\n    }<br \/>\n  }<br \/>\n}<\/p>\n<p>pcm.mout {<br \/>\n  type plug<br \/>\n  slave.pcm mdev<br \/>\n  route_policy \"duplicate\"<br \/>\n}<\/p>\n<p>pcm.mdev {<br \/>\n        type multi<\/p>\n<p>        slaves.a.pcm \"hw:Loopback,0,0\"<br \/>\n        slaves.a.channels 2<br \/>\n        slaves.b.pcm \"hw:0,0\"<br \/>\n        slaves.b.channels 2<\/p>\n<p>        bindings.0.slave a<br \/>\n        bindings.0.channel 0<br \/>\n        bindings.1.slave a<br \/>\n        bindings.1.channel 1<br \/>\n        bindings.2.slave b<br \/>\n        bindings.2.channel 0<br \/>\n        bindings.3.slave b<br \/>\n        bindings.3.channel 1<br \/>\n}<br \/>\n<\/code><\/p>\n<p>2.  Copy the following into a new file \/etc\/modprobe.d\/alsa-loop.conf on the Raspberry Pi (again, as root):<br \/>\n<code><br \/>\nsoftdep snd-bcm2835 post: snd-aloop<br \/>\n<\/code><\/p>\n<p>3.  Add &#8220;-O mout&#8221; to the rx.py command line.<\/p>\n<p>4.  Install darkice on the Raspberry Pi:<br \/>\n<code><br \/>\nsudo apt-get install darkice<br \/>\n<\/code><\/p>\n<p>5.  Copy the following into a new file \/etc\/darkice.cfg on the Raspberry Pi (once again, as root), and replacing the password, server name, etc. with your local info:<br \/>\n<code><br \/>\n# sample DarkIce configuration file, edit for your needs before using<br \/>\n# see the darkice.cfg man page for details<\/p>\n<p># this section describes general aspects of the live streaming session<br \/>\n[general]<br \/>\nduration        = 0        # duration of encoding, in seconds. 0 means forever<br \/>\nbufferSecs      = 5         # size of internal slip buffer, in seconds<br \/>\nreconnect       = yes       # reconnect to the server(s) if disconnected<br \/>\nrealtime        = yes       # run the encoder with POSIX realtime priority<br \/>\nrtprio          = 3         # scheduling priority for the realtime threads<\/p>\n<p># this section describes the audio input that will be streamed<br \/>\n[input]<br \/>\ndevice          = loop      # OSS DSP soundcard device for the audio input<br \/>\nsampleRate      = 11025     # sample rate in Hz. try 11025, 22050 or 44100<br \/>\nbitsPerSample   = 16        # bits per sample. try 16<br \/>\nchannel         = 1         # channels. 1 = mono, 2 = stereo<\/p>\n<p># this section describes a streaming connection to an IceCast2 server<br \/>\n# there may be up to 8 of these sections, named [icecast2-0] ... [icecast2-7]<br \/>\n# these can be mixed with [icecast-x] and [shoutcast-x] sections<br \/>\n[icecast2-0]<br \/>\nbitrateMode     = abr       # average bit rate<br \/>\nformat          = vorbis    # format of the stream: ogg vorbis<br \/>\nbitrate         = 96        # bitrate of the stream sent to the server<br \/>\nserver          = MY_ICECAST_SERVER<br \/>\n                            # host name of the server<br \/>\nport            = 8000      # port of the IceCast2 server, usually 8000<br \/>\npassword        = MY_ICECAST_PASSWORD    # source password to the IceCast2 server<br \/>\nmountPoint      = op25.ogg  # mount point of this stream on the IceCast2 server<br \/>\nname            = OP25 Scanner<br \/>\n                            # name of the stream<br \/>\ndescription     = OP 25 Scanner listening to MY_SYSTEM<br \/>\n                            # description of the stream<br \/>\nurl             = http:\/\/MY_URL.com<br \/>\n                            # URL related to the stream<br \/>\ngenre           = Public Safety    # genre of the stream<br \/>\npublic          = yes       # advertise this stream?<br \/>\nlocalDumpFile\t= dump.ogg  # local dump file<br \/>\n<\/code><\/p>\n<p>6.  Note that this version of darkice does *not* support mp3 format; to get that you will need to compile from source, and I&#8217;m not going to go into that here.<\/p>\n<p>7.  Darkice can stream to an external site like <A HREF=\"https:\/\/broadcastify.zendesk.com\/hc\/en-us\">Broadcastify<\/A> though I am using mine to stream to a local <A HREF=\"icecast.org\">Icecast<\/A> server for consumption on my local network.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Thanks to Graham Norbury, here is how to set up a Raspberry Pi OP25 scanner to stream audio to an icecast or other streaming server. I have updated my plug-and-play&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","ngg_post_thumbnail":0,"footnotes":""},"categories":[33,9],"tags":[37,31,29],"class_list":["post-307","post","type-post","status-publish","format-standard","hentry","category-rapsberry-pi","category-sdr","tag-op25","tag-rtl-sdr","tag-scanner"],"_links":{"self":[{"href":"https:\/\/blog.febo.com\/index.php?rest_route=\/wp\/v2\/posts\/307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.febo.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.febo.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.febo.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.febo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=307"}],"version-history":[{"count":5,"href":"https:\/\/blog.febo.com\/index.php?rest_route=\/wp\/v2\/posts\/307\/revisions"}],"predecessor-version":[{"id":313,"href":"https:\/\/blog.febo.com\/index.php?rest_route=\/wp\/v2\/posts\/307\/revisions\/313"}],"wp:attachment":[{"href":"https:\/\/blog.febo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.febo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.febo.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}