Sound

From Esolang
Jump to navigation Jump to search

Sound is a esolang made by Mihai Popa. You only use notes as programs, similar to Look!. But I changed the notes…

Commands

Commands
Note brainfuck
C +
C# or D -
D# ,
E or F .
F# or G >
G# or A <
A# [
B ]

Interpreter

Python

Note: I didn't code myself, I changed it myself from None1's Look! Interpreter in Python. Source: [1]

"""
The interpreter of the sound-based esoteric programming language Sound
Requires: mido, pygame
See detailed documentation of the language on esolang wiki: https://esolangs.org/wiki/Sound
"""
from os import environ
environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
from mido import MidiFile,MidiTrack,Message,MetaMessage,bpm2tempo
from random import *
import pygame
import sys
def bf(code):
    s=[]
    matches={}
    tape=[0]*1000000
    for i,j in enumerate(code):
        if j=='[':
            s.append(i)
        if j==']':
            m=s.pop()
            matches[m]=i
            matches[i]=m
    cp=0
    p=0
    while cp<len(code):
        if code[cp]=='+':
            tape[p]=(tape[p]+1)%256
        if code[cp]=='-':
            tape[p]=(tape[p]-1)%256
        if code[cp]==',':
            ch=sys.stdin.read(1)
            tape[p]=(ord(ch) if ch else 0)%256
        if code[cp]=='.':
            print(chr(tape[p]),end='')
        if code[cp]=='<':
            p-=1
        if code[cp]=='>':
            p+=1
        if code[cp]=='[':
            if not tape[p]:
                cp=matches[cp]
        if code[cp]==']':
            if tape[p]:
                cp=matches[cp]
        cp+=1
notes=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B']
note2fuck='+--,..>><<[]'
fuck2note={}
for j,i in enumerate(note2fuck):
    if i in fuck2note:
        fuck2note[i].append(notes[j])
    else:
        fuck2note[i]=[notes[j]]
def brainfuck2notes(brainfuck):
    return [choice(fuck2note[i]) for i in brainfuck]
def notes2brainfuck(notes_):
    return ''.join([note2fuck[notes.index(i)] for i in notes_])
def notes2mid(notes_,fn,bpm=120,velocity=127):
    file=MidiFile()
    track=MidiTrack()
    file.tracks.append(track)
    track.append(MetaMessage('set_tempo', tempo=bpm2tempo(bpm)))
    for i in notes_:
        track.append(Message('note_on',note=60+notes.index(i),velocity=velocity,time=0))
        track.append(Message('note_off', note=60 + notes.index(i), time=480))
    file.save(fn)
def playmid(fn):
    pygame.mixer.init()
    pygame.mixer.music.load(fn)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pass
def mid2notes(fn):
    file=MidiFile(fn)
    track=file.tracks[0]
    result=[]
    for msg in track:
        if msg.type=='note_on':
            result.append(notes[msg.note%12])
    return result
def interpret(fn):
    bf(notes2brainfuck(mid2notes(fn)))
if __name__=='__main__':
    def helper():
        print(f'Usage: {sys.executable} {sys.argv[0]} <command> <filename>\nCommands:\ninterpret: Interprets a Sound program.\nfuck: Converts a Sound program to brainfuck code and prints it.\nplay: Plays a Sound program as audio\nnotes: Outputs the notes in a Sound program.\nunfuck: Input some brainfuck code and encode it into a Sound program.\nunnotes: Input some notes and write them into a Sound program.')
    a=sys.argv
    if len(a)==3:
        argument=a[1]
        if argument=='interpret':
            interpret(a[2])
        if argument=='fuck':
            print(notes2brainfuck(mid2notes(a[2])))
        if argument=='play':
            playmid(a[2])
        if argument=='notes':
            print(' '.join(mid2notes(a[2])))
        if argument=='unfuck':
            code=input('Please enter some brainfuck code:')
            notes2mid(brainfuck2notes(code),a[2])
        if argument=='unnotes':
            code=input('Please enter some notes separated by spaces:')
            notes2mid(code.split(),a[2])
        if argument not in 'interpret fuck play notes unfuck unnotes'.split():
            helper()
    else:
        helper()

Examples

Hello, world! (as compressed MIDI & encoded as Base64)

UEsDBBQAAAAIADVIglfc01GuvwAAANMFAAAKAAAAaGVsbG8ubWlkafMNyUhhYGBgY2BkYGR84BtSlM3AwLqX4X8gM/tCBYYJNvXNCQ02DhQz3EAMNyDDCcRwcqCeya4ghiuQYQti2AIZ7iCGO5DhDGI4U9EuRxDDkWKT8YUP1U0mKQztQAw75DAkL77gAUWtACfGQAcQwwGHmwcy9bqAGC5YkyhJBsI9CI8muIFwEUwGphq4CCYDUzvcUngigXsHk4Hq5gFjYOZTOIOkhERS0MEZcCtIigLMkMc0EJ5aMJMNTM1/fQYAUEsBAh8AFAAAAAgANUiCV9zTUa6/AAAA0wUAAAoAJAAAAAAAAAAgAAAAAAAAAGhlbGxvLm1pZGkKACAAAAAAAAEAGABtNMZn7STaARtmpU/tJNoBG2alT+0k2gFQSwUGAAAAAAEAAQBcAAAA5wAAAAAA

Hello, world! (as notes)

C C C C C C C C A# F# C C C C C C C C A C# B G C C C C C C C C F G C C C C C C C C A# G C C C C C C C C C C C C A D B F# C C C C C F C C C C C C C F F C C C E F # C C C C C C C C A# F# C C C C C G# C# B F# C C C C E D C# D D D C# D C# C# C# D D E A G# G# G# C C C C C C C C C C C C C C C F G G F C C C E C# D C# C# C# C# F D C# D C# C# D D C# F F# F# C F

Cat (as MIDI & encoded as Base64)

TVRoZAAAAAYAAQABAeBNVHJrAAAAOAD/UQMHoSAAkD9/g2CAP0AAkEZ/g2CARkAAkEB/g2CAQEAAkD9/g2CAP0AAkEd/g2CAR0AA/y8A

Cat (as notes)

D# A# E D# B

99 bottles of beer (as compressed MIDI & encoded as Base64)

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

99 bottles of beer (as compressed text file with notes & encoded as Base64)

UEsDBBQAAAAIAFFLgldoJxZ71wMAAJAbAAAQAAAAOTliZWVyX25vdGVzLnR4dMVZW47kIAz8X2nvEImTEB6+/422wTxssB2yo5lRWtPpJARsl12FB67sriAc3l3xgs8RLnCX/xwgP/gZD9ct3KivjmXY+ARX3gs4BnCOOj+b6C7XPD5druIFvIaXb/LKbz5ymS9+juDwrP2M5CK7xX6Qx9eH2PD5Y57l/unWevzzIxbPlaxGsnXvT8q2aRcWnzVkDMs5GCXjocKj3krLoDHQ6zjB4QV02fBIYudZCG7e7Mo7VJc0CK5jH7/63fsCgv4a/+oVRH+s9wUfMaODs6wOM219fap+0rJi32/7/jjM1IXVxd6cIbMhJ5EJ3TN3X0Lqrl0835xSp1tdIK5qvjSX83fr6uN9RVy7ZqJHXaEyD8Wk4rXdLGl4qFDNEzXZnWAEynMkbtm9R9ca/b1UsMxP/VoivhJWa4CsREMkM+/K2BruJ4fF1d5ed8AtlbBNi7diM0H2A6kEIkTBHXhw5qaKsDBQzWpLmdCLlQXq71+i1STySty4YSWTnWGixkNRfDg7ipkfotQkG7qyyANZLhRrsCuewSzZK6ZF2JHSaKW+4bEl6S1/zDG0PDDr0m7aqA+UTj0mIYF9t9g3PQkjk3dCRdyXKzalxieowLR9lLLgBtDukYaBTgfj+zlAMKnHig64Y3qQEyVZFUueAKwyfIKbyTkdHEmtqeVQmMKkSKZ5JjHKrxfeaxsh4MDghVBXIE+9yWudQrqpWjSyJopf4yQRlGirY5F/1mAt3LIGMzxN8iCgww7dS7c2pOAS5fuGoKk8TTIfUUc96RNlHhpLYaO17zvgIWXJlgl9MlJJCB8fKksTuOAtvoAyjR5BsrI3yllir9NNEVlXErIN74hAzC0M3JjMASET27yb5bL26NJ15WZpo8REmjsO7aFdmewW+QhEQvomI6E1gDxqT1Kqci9QNxuopjb6m4AL5lSM3WEl99B8k53ULcpO7jUxTdyYeSyV03f45iPJ6bwoPUMsSyLQko204dI3Dg0I33xoes/S8eVsG6NsF1ZZTftLo6WBGUW04mx6AMkDGDVjuCqU3yLS8RVTXUbaM3nf/ABNix/wfuDtHE/zV95b23rzP6o82yOft9eSAPS0pcRuXfsTZ2RhD2xftLL7HYIcvthWqxOStlqcwEN/rj21PjGfrA6wyZcH81ioMuZKcq83uC8IT7Ube7oN6IjJZ9sAUfX4pynUjvE+0hAvUZdQlps6Vyv7pSfW4fJTLHrtKz8K3acNp6jzDkM6u2vJUDWkcHP/ujpQebu2VbWMWnrAtFJSOQSOcQSwSrL9g4qUktHqBWvNkRXmpmX+/vkHUEsBAh8AFAAAAAgAUUuCV2gnFnvXAwAAkBsAABAAJAAAAAAAAAAgAAAAAAAAADk5YmVlcl9ub3Rlcy50eHQKACAAAAAAAAEAGACyhQzh8CTaARBPYeDwJNoBEE9h4PAk2gFQSwUGAAAAAAEAAQBiAAAABQQAAAAA

Never Gonna Give You Up (as compressed MIDI & encoded as Base64)

Too long. You can see here: Sound/Rickroll

Never Gonna Give You Up (as compressed text file with notes & encoded as Base64)

Quite long. You can see here: Sound/Rickroll (as text)

See also