Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring in the new C dpwe piano into Tulip #438

Merged
merged 4 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion amy
2 changes: 0 additions & 2 deletions tulip/amyboard/boards/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,5 @@
freeze("$(MPY_DIR)/../amy", "amy.py")
freeze("$(MPY_DIR)/../amy", "juno.py")
freeze("$(MPY_DIR)/../amy", "amy_wave.py")
freeze("$(MPY_DIR)/../amy/experiments", "tulip_piano.py")
freeze("$(MPY_DIR)/../amy/experiments", "piano_params.py")

#freeze("$(MPY_DIR)/lib/micropython-lib/micropython/utarfile", "utarfile.py")
2 changes: 0 additions & 2 deletions tulip/amyrepl/variants/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
# core scheduler replaced with a custom scheduler that uses the JavaScript
# runtime (with setTimeout an Promise's) to contrtol the scheduling.
freeze("../../../../amy", "amy.py")
freeze("../../../../amy/experiments", "tulip_piano.py")
freeze("../../../../amy/experiments", "piano_params.py")
freeze("../../../../amy", "juno.py")

package(
Expand Down
2 changes: 0 additions & 2 deletions tulip/esp32s3/boards/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,4 @@
freeze("$(MPY_DIR)/../amy", "amy.py")
freeze("$(MPY_DIR)/../amy", "juno.py")
freeze("$(MPY_DIR)/../amy", "amy_wave.py")
freeze("$(MPY_DIR)/../amy/experiments", "tulip_piano.py")
freeze("$(MPY_DIR)/../amy/experiments", "piano_params.py")
#freeze("$(MPY_DIR)/lib/micropython-lib/micropython/utarfile", "utarfile.py")
1 change: 1 addition & 0 deletions tulip/esp32s3/esp32_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ list(APPEND MICROPY_SOURCE_EXTMOD
${AMY_DIR}/src/partials.c
${AMY_DIR}/src/pcm.c
${AMY_DIR}/src/log2_exp2.c
${AMY_DIR}/src/interp_partials.c
${ULAB_DIR}/scipy/integrate/integrate.c
${ULAB_DIR}/scipy/linalg/linalg.c
${ULAB_DIR}/scipy/optimize/optimize.c
Expand Down
2 changes: 0 additions & 2 deletions tulip/linux/variants/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@
freeze("$(MPY_DIR)/../amy", "amy.py")
freeze("$(MPY_DIR)/../amy", "juno.py")
freeze("$(MPY_DIR)/../amy", "amy_wave.py")
freeze("$(MPY_DIR)/../amy/experiments", "tulip_piano.py")
freeze("$(MPY_DIR)/../amy/experiments", "piano_params.py")

2 changes: 0 additions & 2 deletions tulip/macos/variants/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@
freeze("$(MPY_DIR)/../amy", "amy.py")
freeze("$(MPY_DIR)/../amy", "juno.py")
freeze("$(MPY_DIR)/../amy", "amy_wave.py")
freeze("$(MPY_DIR)/../amy/experiments", "tulip_piano.py")
freeze("$(MPY_DIR)/../amy/experiments", "piano_params.py")

8 changes: 7 additions & 1 deletion tulip/shared/py/midi.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ def __init__(self, voices_per_channel, patch_per_channel, show_warnings=True):
patch = patch_per_channel[channel] if channel in patch_per_channel else None
self.add_synth(channel, patch, num_voices)

def add_synth_object(self, channel, synth_object):
def release_synth_for_channel(self, channel):
if channel in self.synth_per_channel:
# Old Synth allocated - Expicitly return the amy_voices to the pool.
self.synth_per_channel[channel].release()
del self.synth_per_channel[channel]
if channel in self.arpeggiator_per_channel:
self.arpeggiator_per_channel[channel].synth = None

def add_synth_object(self, channel, synth_object):
self.release_synth_for_channel(channel)
self.synth_per_channel[channel] = synth_object
if channel in self.arpeggiator_per_channel:
self.arpeggiator_per_channel[channel].synth = synth_object
Expand All @@ -36,6 +41,7 @@ def add_synth(self, channel=1, patch_number=0, num_voices=6):
elif channel == 16:
synth_object = OscSynth(num_voices=1) # the "system bleep" synth
else:
self.release_synth_for_channel(channel)
synth_object = Synth(num_voices=num_voices, patch_number=patch_number)
self.add_synth_object(channel, synth_object)

Expand Down
3 changes: 2 additions & 1 deletion tulip/shared/py/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@
"OCTAVE WAR",
"GRAND PRIX",
"ST.HELENS ",
"EXPLOSION "
"EXPLOSION ",
"dpwe Piano"


]
2 changes: 1 addition & 1 deletion tulip/shared/py/voices.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def update_patches(synth):
if(synth=='Custom'):
app.patchlist.replace_items([("Custom %d" % x) for x in range(32)])
if(synth=='Misc'):
app.patchlist.replace_items([])
app.patchlist.replace_items([patches[256]])
app.patchlist.label.set_text("%s patches" % (synth))

def sync_ui_for_channel(channel):
Expand Down
160 changes: 160 additions & 0 deletions tulip/shared/py/world_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# world-async.py
# async version of tulip world
# at first for just the web ports

import json
import js
import asyncio
import os
from world import MAX_DESCRIPTION_SIZE, MAX_USERNAME_SIZE, username, _isdir, nice_time, read_in_chunks
from world import ta, tb, text_channel_id, files_channel_id, text_base_url, files_base_url, headers, discord_epoch
from world import unique_files, ls, prompt_username


# get the last n messages
def messages(n=500, chunk_size = 100, mtype='text'):
ret = []
before = None

base_url = files_base_url
if(mtype == 'text'): base_url = text_base_url

# First one is the newest
# https://discord.com/developers/docs/resources/channel#get-channel-messages
if(n<chunk_size): chunk_size = n
response = requests.get(base_url+"messages?limit=%d" % (chunk_size), headers = headers)
# We get a x-ratelimit-reset from the headers here, we can use that to know what time it is
# We have to do it this way because (1) micropython does not have datetime/dateutil
# and (2) we often do not know what time it is on Tulip
server_time_ms = (int(response.headers['x-ratelimit-reset'])-1)*1000

# Pull up to n messages from discord, using paging
all_responses = response.json()
while(len(all_responses)<n and len(response.json())==chunk_size):
oldest_id = response.json()[-1]['id']
response = requests.get(base_url+"messages?limit=%d&before=%s" % (chunk_size, oldest_id), headers=headers)
all_responses = all_responses + response.json()


for i in all_responses[:n]:
try:
# Discord trims spaces at the end of content
if(i['content'].endswith('#')): i['content']=i['content']+' '
(username, content) = i['content'].split(" ### ")
except ValueError: # not a valid TW message / file
continue
r = {
# Discord IDs have epoch ms (since 2015) encoded in them
'age_ms':server_time_ms - ((int(i['id']) >> 22) + discord_epoch),
'time':((int(i['id']) >> 22) + discord_epoch),
'username':username,
'content':content
}
if mtype=='text' and len(i['attachments']) == 0:
ret.append(r)

if mtype=='files' and len(i['attachments']) > 0:
a = i['attachments'][0]
r.update({
'filename':a['filename'],
'size':a['size'],
'url':a['url'],
'content_type':a['content_type']
})
ret.append(r)
return ret

def download(filename, username=None, limit=5000, chunk_size=4096):
got = None
# Check for an extension
if('.' not in filename[-5:]):
filename = filename + ".tar"
for file in messages(n=limit, mtype='files'):
if(file["filename"] == filename):
if username is None or username==file['username']:
got = file
break
if got is not None:
age_nice = nice_time(got["age_ms"])
grab_url = got["url"] # Will get the latest (most recent) file with that name

r = tulip.url_save(got['url'], filename)

print("Downloaded %s by %s [%d bytes, last updated %s] from Tulip World." % (filename,got['username'], got['size'], age_nice.lstrip()))
if(filename.endswith('.tar')):
print("Unpacking %s. Run it with run('%s')" % (filename, filename[:-4]))
tulip.tar_extract(filename, show_progress=False)
os.remove(filename)
else:
if(username is None):
print("Could not find %s on Tulip World" % (filename))
else:
print("Could not find %s by %s on Tulip World" % (filename, username))



# uploads a file
def upload(filename, description=""):
u = prompt_username()
if u is None:
return

tar = False
if(_isdir(filename)):
tar = True
print("Packing %s" % (filename))
tulip.tar_create(filename)
filename += ".tar"

filesize = os.stat(filename)[6]
f = open(filename, 'rb')

# First get the url to upload to
api_response = requests.post(
files_base_url+"attachments",
headers=headers,
json={"files": [{"filename": filename, "file_size": filesize, "id": 1}]},
)

# Then PUT the file to the url
attachment_info = api_response.json()["attachments"][0]
put_url = attachment_info["upload_url"]
put_response = requests.put(
put_url,
headers={
"Authorization": headers['Authorization'],
"User-Agent": headers['User-Agent'],
"Content-Length": str(filesize),
"Content-Type": "application/octet-stream",
},
data=f,
)

# Lastly, post a message with the uploaded filename
payload = {
"content":u + " ### " + description[:MAX_DESCRIPTION_SIZE],
"attachments": [{
"id": attachment_info['id'],
"uploaded_filename":attachment_info['upload_filename'],
"filename":filename
}]
}
r = requests.post(files_base_url+"messages", headers = headers, data = json.dumps(payload))

print("Uploaded %s to Tulip World." % (filename))
if(tar):
os.remove(filename)


def post_message(message):
u = prompt_username()
if u is None:
return
r = requests.post(text_base_url+"messages", headers = headers, data = json.dumps ( {"content":u + " ### " + message} ))







1 change: 1 addition & 0 deletions tulip/shared/tulip.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ EXTMOD_SRC_C += $(addprefix $(TOP)/../amy/src/, \
partials.c \
pcm.c \
log2_exp2.c \
interp_partials.c \
)

EXTMOD_SRC_C += $(addprefix $(TULIP_EXTMOD_DIR)/, \
Expand Down
2 changes: 0 additions & 2 deletions tulip/web/variants/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
freeze("../../../amy", "amy.py")
freeze("../../../amy", "juno.py")
freeze("../../../amy", "amy_wave.py")
freeze("../../../amy/experiments", "tulip_piano.py")
freeze("../../../amy/experiments", "piano_params.py")

package(
"asyncio",
Expand Down
Loading
Loading