Translate Morse code based on tone duration

APL (Dyalog), 65 62 60 57 bytes

-3 thanks to ngn.

Tacit prefix function.

⎕CY'dfns'
morse'/|[-.]+'⎕S'&'∘(⊃∘'/. -'¨6|'1+|(00)+'⎕S 1)

Try it online! Header, f←, and Footer are just to allow calling the function from Input while retaining TIO's byte count. In a normal APL session (corresponding to TIO's Input field), it would not be needed.

⎕CY'dfns'copy the dfns workspace (library)

() apply this tacit function:
'1+|(00)+'⎕S 1 PCRE Search 1-runs and even-length 0-runs and return matches' lengths
6| division remainder when divided by 6
⊃∘'/. -'¨ for each match length, pick the corresponding character from this string
'/|[-.]+'⎕S'&'∘ PCRE Search slashes and dash/dot-runs and return those
morse translate from Morse code to regular text


Python 2, 142 135 bytes

lambda s:''.join(' E-T----Z-Q---RSWU--2FH-V980NIMA--1CBYX-6--GDOK534PLJ-7'[int('0'+l.replace('111','3'),16)%57]for l in s.split('000'))

Try it online!

Explanation:

Splits the string into letters on 000 (0 thus means space)

Replaces each 111 with 3, and converts into base 16.

Then each number is modded by 57, which gives a range of 0..54, which is the index of the current character.


Previous version that converted to base 3:

Python 2, 273 252 247 bytes

lambda s:''.join(chr(dict(zip([0,242,161,134,125,122,121,202,229,238,241]+[2]*7+[5,67,70,22,1,43,25,40,4,53,23,49,8,7,26,52,77,16,13,2,14,41,17,68,71,76],[32]+range(48,91)))[int('0'+l.replace('111','2').replace('0',''),3)])for l in s.split('000'))

Try it online!

Previous version that converted to binary:

Python 2, 282 261 256 bytes

lambda s:''.join(chr(dict(zip([0,489335,96119,22391,5495,1367,341,1877,7637,30581,122333]+[2]*7+[23,469,1885,117,1,349,477,85,5,6007,471,373,119,29,1911,1501,7639,93,21,7,87,343,375,1879,7543,1909],[32]+range(48,91)))[int('0'+l,2)])for l in s.split('000'))

Try it online!


Ruby, 123 bytes

->s{s.split(/0000?/).map{|r|r[0]?"YE9_0IZTO_BHKU58V_GR_SFA__1_4NP_60X_____C__D_ML7WQ3__2__J"[r.to_i(2)%253%132%74]:" "}*""}

Try it online!

Split the input string on character limit. Use 3 or 4 OFF bits so that spaces are converted to empty strings. Take the base 2 value of every character, and bring into a reasonable range (less than 60 possible values) using modulo on 3 successive divisions.