This beatmap was submitted using in-game submission on Saturday, May 21, 2016 at 12:02:38 PM
Artist: DM DOKURO
Title: SAVE
Source: UNDERTALE
Tags: toby radiation fox Asriel Dreemur Hopes Dreams
BPM: 180
Filesize: 9640kb
Play Time: 05:13
Difficulties Available:
Information: Scores/Beatmap Listing
---------------
This map contains Undertale spoilers!
WIP
The storyboard was made using osbpy.
The SB load does exceed 5 during two parts in the map. Each time only lasts about 0.1 seconds, so I don't think this is a problem.
[Storyboard Code]
Artist: DM DOKURO
Title: SAVE
Source: UNDERTALE
Tags: toby radiation fox Asriel Dreemur Hopes Dreams
BPM: 180
Filesize: 9640kb
Play Time: 05:13
Difficulties Available:
- And then you'll lose to me again. And again. And again!!! (5.64 stars, 1085 notes)
Information: Scores/Beatmap Listing
---------------
This map contains Undertale spoilers!
WIP
The storyboard was made using osbpy.
The SB load does exceed 5 during two parts in the map. Each time only lasts about 0.1 seconds, so I don't think this is a problem.
[Storyboard Code]
storyboard.py
from osbpy import *
from math import *
beat = 333
start = 31
def introMovement(sprite, offset = 0):
sprite.loop(start, (21364-start)//(8*beat))
sprite.moveY(17, 0, 4*beat, 240 + offset, 245 + offset, True)
sprite.moveY(17, 4*beat, 8*beat, 245 + offset, 240 + offset, True)
def regularMovement(sprite, offsetX, offsetY, scaleY = 1, delay = 0):
sprite.loop(21364 + delay, (309364-21364)//(16*beat));
sprite.moveX(16, 0, 4*beat, 320 + offsetX, 120 + offsetX, True)
sprite.moveX(15, 4*beat, 8*beat, 120 + offsetX, 320 + offsetX, True)
sprite.moveX(16, 8*beat, 12*beat, 320 + offsetX, 520 + offsetX, True)
sprite.moveX(15, 12*beat, 16*beat, 520 + offsetX, 320 + offsetX, True)
sprite.loop(21364 + delay, (309364-21364)//(12*beat));
sprite.moveY(16, 0, 3*beat, 240 + offsetY, 240 + int(60 * scaleY) + offsetY, True)
sprite.moveY(15, 3*beat, 6*beat, 240 + int(60 * scaleY) + offsetY, 240 + offsetY, True)
sprite.moveY(16, 6*beat, 9*beat, 240 + offsetY, 240 - int(60 * scaleY) + offsetY, True)
sprite.moveY(15, 9*beat, 12*beat, 240 - int(60 * scaleY) + offsetY, 240 + offsetY, True)
def flash(s, alpha = 1):
s.loop(21364, (42697 - 21364)//beat + 1)
s.fade(0, 0, beat, alpha, 0, True)
s.loop(64030, (85364 - 64030)//beat + 1)
s.fade(0, 0, beat, alpha, 0, True)
s.loop(192030, (234697 - 192030)//beat + 1)
s.fade(0, 0, beat, alpha, 0, True)
s.loop(256030, (298697 - 256030)//beat)
s.fade(0, 0, beat, alpha, 0, True)
s.fade(0, 298697, 300030, alpha, 0.3 * alpha)
s.fade(0, 300030, 302697, 0.3 * alpha, alpha)
s.fade(0, 302697, 304030, alpha, 0)
flashTimes = [304030, 304197, 304530, 304697, 305030, 305197, 305530, 305697, 306030, 306364]
for i in flashTimes:
s.fade(0, i, i + beat//4, alpha, 0)
s.fade(0, 306697, 309364 - beat, alpha, 0)
removeBackground = osbject("undertale.png", "Background", "Centre", 320, 240)
frame_rate, music = wavfile.read("audio.wav")
music_channel0 = music[:, 0]
music_channel1 = music[:, 1]
'''
spectrum0, spec0_freqs, spec0_t, spec0_im = plt.specgram(music_channel0, NFFT=1024, Fs = frame_rate, noverlap=5, mode='magnitude')
spec0_max = plt.amax(spectrum0)
spec0_min = plt.amin(spectrum0)
spectrum1, spec1_freqs, spec1_t, spec1_im = plt.specgram(music_channel0, NFFT=1024, Fs = frame_rate, noverlap=5, mode='magnitude')
spec1_max = plt.amax(spectrum1)
spec1_min = plt.amin(spectrum1)
'''
def backgroundColor(s, offset = False):
offsetA = randint(-600, 600) if offset else 0
s.loop(21364 + offsetA, int((245364-21364)/(beat * 24)))
s.color(11, 0, beat * 8, 0, 0, 255, 255, 0, 0, True)
s.color(11, beat * 8, beat * 16, 255, 0, 0, 0, 126, 0, True)
s.color(11, beat * 16, beat * 24, 0, 126, 0, 0, 0, 255, True)
s.color(0, 245364, 248030, 0, 0, 255, 20, 20, 20)
rs = [255, 255, 255, 235, 156, 65, 1, 0, 0, 0, 0, 0, 0, 72, 193, 251]
gs = [36, 130, 221, 252, 239, 202, 180, 194, 225, 234, 130, 54, 3, 0, 0, 0]
bs = [0, 0, 0, 3, 13, 28, 57, 111, 187, 255, 213, 168, 144, 151, 182, 197]
s.loop(256030, (309364 - 256030)/(beat * 16))
for i in range(16):
j = (i+1)%16
s.color(0, i*beat, (i+1)*beat, rs[i], gs[i], bs[i], rs[j], gs[j], bs[j], True)
def barEffect(numBars, xOffset, xDist, width, minHeight, heightRange, heightPeriod, heightOffset, alpha, bottom = True):
for i in range(numBars):
#print(i)
anchor = "BottomCentre" if bottom else "TopCentre"
squareType = "sb/bottom_square.png" if bottom else "sb/top_square.png"
yPos = 440 + heightOffset if bottom else 40 - heightOffset
angle = -pi/6 if bottom else pi/6
squareA = osbject(squareType, "Background", anchor, 320 - xOffset, yPos)
squareB = osbject(squareType, "Background", anchor, 320 + xOffset, yPos)
squareA.para(0, 21364, 309364, "A")
squareB.para(0, 21364, 309364, "A")
squareA.loop(21364, (309364-21364)//120000 + 1)
squareA.rotate(16, 0, 30000, angle, 0, True)
squareA.rotate(15, 30000, 60000, 0, -angle, True)
squareA.rotate(16, 60000, 90000, -angle, 0, True)
squareA.rotate(15, 90000, 120000, 0, angle, True)
squareB.loop(21364, (309364-21364)//120000 + 1)
squareB.rotate(16, 0, 30000, -angle, 0, True)
squareB.rotate(15, 30000, 60000, 0, angle, True)
squareB.rotate(16, 60000, 90000, angle, 0, True)
squareB.rotate(15, 90000, 120000, 0, -angle, True)
squareA.loop(21364 + i * beat, int((309364-21364)/(beat * numBars)))
squareA.fade(0, 0, beat, 0, alpha, True)
squareA.fade(0, beat * numBars - beat//2, beat * numBars, alpha, 0, True)
squareA.moveX(1, 0, beat * numBars, 320 - xOffset, 320 - xOffset - xDist, True)
squareB.loop(21364 + i * beat, int((309364-21364)/(beat * numBars)))
squareB.fade(0, 0, beat, 0, alpha, True)
squareB.fade(0, beat * numBars - beat//2, beat * numBars, alpha, 0, True)
squareB.moveX(1, 0, beat * numBars, 320 + xOffset, 320 + xOffset + xDist, True)
backgroundColor(squareA, True)
backgroundColor(squareB, True)
squareA.loop(21364 + i * beat, (309364-21364)//(beat * heightPeriod))
squareA.vecscale(17, 0, heightPeriod * beat // 2, width, minHeight, width, minHeight + heightRange, True)
squareA.vecscale(17, heightPeriod * beat // 2, heightPeriod * beat, width, minHeight + heightRange, width, minHeight , True)
squareB.loop(21364 + i * beat, (309364-21364)//(beat * heightPeriod))
squareB.vecscale(17, 0, heightPeriod * beat // 2, width, minHeight, width, minHeight + heightRange, True)
squareB.vecscale(17, heightPeriod * beat // 2, heightPeriod * beat, width, minHeight + heightRange, width, minHeight , True)
''' Spectrum disabled because too laggy
lastHeight = (spectrum[i][0]-spec_min)/(spec_max - spec_min)*heightRange + minHeight
lastHeight = math.ceil(lastHeight * 1000)/1000;
lastTime = int(round(spec_t[0]*1000))
for index, power in enumerate(spectrum[i]):
power = (power-spec_min)/(spec_max-spec_min)*heightRange + minHeight
power = math.ceil(power*1000)/1000
if power == lastHeight or int(round(spec_t[index]*1000)) < 21364 or int(round(spec_t[index]*1000)) > 309364 or index % 2 is not 0:
lastTime = int(round(spec_t[index]*1000))
continue
else:
squareA.vecscale(2, lastTime, int(round(spec_t[index]*1000)), width, lastHeight, width, power)
squareB.vecscale(2, lastTime, int(round(spec_t[index]*1000)), width, lastHeight, width, power)
'''
barEffect(4, 0, 600, 1.4, 2, 3, 4, 30, 0.9)
barEffect(4, 0, 600, 1.4, 2, 3, 4, 30, 0.9, False)
barEffect(6, -20, 600, 1, 3, 2.5, 3, 10, 0.7)
barEffect(6, -20, 600, 1, 3, 2.5, 3, 10, 0.7, False)
barEffect(6, -40, 500, 0.8, 4, 2, 2, -10, 0.5)
barEffect(6, -40, 500, 0.8, 4, 2, 2, -10, 0.5, False)
barEffect(10, -60, 500, 0.5, 5, 1, 5, -30, 0.3)
barEffect(10, -60, 500, 0.5, 5, 1, 5, -30, 0.3, False)
''' Sound wave effect (disabled because too laggy)
stepsize = 33
waveEffect = []
for i in range(20):
square = osbject("sb/white_square_small.png", "Foreground", "CentreLeft", i * 32, 240)
square.loop(21364, int((309364-21364)/(beat * 3)));
square.color(17, 0, beat, 0, 0, 255, 255, 0, 0, True);
square.color(17, beat, 2*beat, 255, 0, 0, 0, 255, 0, True);
square.color(17, 2*beat, 3*beat, 0, 255, 0, 0, 0, 255, True);
waveEffect.append(square)
for ms in range(21364, 309364, stepsize):
print(ms)
for i in range(20):
thisSampleId = int((ms + 2 * i) * 44.1)
nextSampleId = int((ms + 2 * (i + 1)) * 44.1)
thisSampleNormalized = music[thisSampleId, 0] / 32767
nextSampleNormalized = music[nextSampleId, 0] / 32767
thisSample = 240 + (thisSampleNormalized) * 80
nextSample = 240 + (nextSampleNormalized) * 80
dy = nextSample - thisSample
dx = 32
length = sqrt(dx * dx + dy * dy)
angle = atan2(dy, dx)
waveEffect[i].moveY(0, ms, ms + stepsize, int(thisSample), int(thisSample))
waveEffect[i].vecscale(0, ms, ms + stepsize, length, 1, length, 1)
waveEffect[i].rotate(0, ms, ms + stepsize, angle, angle)
'''
back_white = osbject("sb/white.png", "Background", "Centre", 320, 240)
back_white.fade(0, 20030, 21364, 0, 1)
back_white.fade(0, 21364, 21364 + beat//4, 1, 0)
back_white.fade(0, 254697, 256030, 0, 1)
back_white.fade(0, 256030, 256030 + beat//4, 1, 0)
rainbow_r = [255, 255, 255, 255, 255, 255, 255, 154, 23, 0, 0, 0, 0, 0, 0, 0]
rainbow_g = [51, 87, 126, 165, 201, 232, 254, 255, 255, 255, 255, 224, 166, 101, 41, 0]
rainbow_b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 239, 255, 255, 255, 255, 255]
trailLength = 16
for i in range(trailLength):
effect = osbject("sb/asriel_full", "Background", "Centre", 320, 215)
effect.fade(0, 21364, 309364, 1 - i/trailLength, 1 - i/trailLength)
effect.color(0, 21364, 309364, rainbow_r[i%16], rainbow_g[i%16], rainbow_b[i%16], rainbow_r[i%16], rainbow_g[i%16], rainbow_b[i%16])
regularMovement(effect, 0, -25, scaleY = 1, delay = i * beat // 16)
for i in range(trailLength//2):
effect = osbject("sb/asriel_full", "Background", "Centre", 320, 215)
idx = (2*i) % 16
effect.color(0, 21364, 309364, rainbow_r[idx], rainbow_g[idx], rainbow_b[idx], rainbow_r[idx], rainbow_g[idx], rainbow_b[idx])
regularMovement(effect, 0, -25, scaleY = 1, delay = 2*i * beat // 16)
effect.para(0, 21364, 309364, "A")
flash(effect, alpha = 1 - 2*i/trailLength)
bodyOffsetX = 0
armOffsetX = 44
armOffsetY = -18
cape2OffsetX = 44
cape2OffsetY = -68
capeOffsetY = -78
headOffsetY = -104
necklaceOffsetY = -64
feetOffsetX = 4
feetOffsetY = 72
feet = osbject("sb/feet.png", "Background", "Centre", 320 + feetOffsetX, 240 + feetOffsetY)
body = osbject("sb/body.png", "Background", "Centre", 320 + bodyOffsetX, 240)
armL = osbject("sb/armL.png", "Background", "Centre", 320 + armOffsetX, 240 + armOffsetY)
armR = osbject("sb/armR.png", "Background", "Centre", 320 - armOffsetX, 240 + armOffsetY)
cape2L = osbject("sb/cape2L.png", "Background", "Centre", 320 + cape2OffsetX, 240 + cape2OffsetY)
cape2R = osbject("sb/cape2R.png", "Background", "Centre", 320 - cape2OffsetX, 240 + cape2OffsetY)
cape = osbject("sb/cape.png", "Background", "Centre", 320, 240 + capeOffsetY)
necklace = osbject("sb/necklace.png", "Background", "Centre", 320, 240 + necklaceOffsetY)
head = osbject("sb/head.png", "Pass", "Centre", 320, 240 + headOffsetY)
head_disappoint = osbject("sb/disappoint.png", "Fail", "Centre", 320, 240 + headOffsetY, framecount = 4, framerate = 250, loop = "LoopForever")
introMovement(body)
introMovement(armL, armOffsetY)
introMovement(armR, armOffsetY)
introMovement(cape2L, cape2OffsetY)
introMovement(cape2R, cape2OffsetY)
introMovement(cape, capeOffsetY)
introMovement(head, headOffsetY)
introMovement(head_disappoint, headOffsetY)
introMovement(necklace, necklaceOffsetY)
introMovement(feet, feetOffsetY)
regularMovement(body, bodyOffsetX, 0, delay = 12)
regularMovement(armL, armOffsetX, armOffsetY, 1.04)
regularMovement(armR, -armOffsetX, armOffsetY, 1.04)
regularMovement(cape2L, cape2OffsetX, cape2OffsetY, 1.01)
regularMovement(cape2R, -cape2OffsetX, cape2OffsetY, 1.01)
regularMovement(cape, 0, capeOffsetY, 1.01)
regularMovement(head_disappoint, 0, headOffsetY, 1.05)
regularMovement(head, 0, headOffsetY, 1.05)
regularMovement(necklace, 0, necklaceOffsetY, 1.02)
regularMovement(feet, feetOffsetX, feetOffsetY, 0.97)
bottomLight = osbject("sb/white_square_gradient.png", "Foreground", "BottomCentre", 320, 480);
bottomLight.para(0, 21364, 309364, "A")
bottomLight.vecscale(0, 21364, 309364, 30, 6, 30, 6);
topLight = osbject("sb/white_square_gradient.png", "Foreground", "TopCentre", 320, 0);
topLight.para(0, 21364, 309364, "A")
topLight.para(0, 21364, 309364, "V")
topLight.vecscale(0, 21364, 309364, 30, 6, 30, 6);
backgroundColor(bottomLight)
backgroundColor(topLight)
flash(bottomLight)
flash(topLight)
undertale = osbject("undertale.png", "Foreground", "Centre", 320, 240)
undertale.fade(0, 0, start + beat, 1, 0)
black = osbject("sb/black.png", "Foreground", "Centre", 320, 240)
black.fade(0, 309030, 309364, 0, 1)
black.fade(0, 309364, 314697, 1, 1)
# output .osu file
path = "redacted"
osbject.end(path)
osbpy.py
from random import randint
import os
import pylab as plt
import math
import numpy as np
from scipy.io import wavfile
layers = ["Background","Fail","Pass","Foreground"]
origins = ["TopLeft","TopCentre","TopRight","CentreLeft","Centre","CentreRight","BottomLeft","BottomCentre","BottomRight"]
spect = []
def sinus(har, radius, sinheight):
x1 = np.linspace(0, sinheight, har)
y1 = np.sin(x1)
sinus = plt.plot(x1, y1, 'bo')
ysinus = sinus[0].get_ydata()*radius
return ysinus
def gencircle(r, n):
for i in range(len(r)):
for j in range(n[i]):
yield r[i], j*(2 * np.pi / n[i])
def circle(har, radius):
circle = []
xcircle = {}
ycircle = {}
for r, t in gencircle([2*radius], [har]):
circle += plt.plot(r * np.cos(t), r * np.sin(t), 'bo')
for index, val in enumerate(circle):
xcircle[index] = val.get_xdata()
ycircle[index] = val.get_ydata()
return ycircle, xcircle
def check_easing(es):
if es not in range(35):
return True
else:
return False
class osbject:
back_obj = []
fail_obj = []
pass_obj = []
fore_obj = []
obj_layers = {"Background" : back_obj, "Fail" : fail_obj, "Pass" : pass_obj, "Foreground" : fore_obj}
def __init__(self, path, layer, origin, posX, posY, framecount=None, framerate=None, loop=None):
osbject.obj_layers[layer].append(self)
valid = True
errors = []
self.props = []
if type(path) is not str:
errors.append("Invalid Path! ")
valid = False
if layer not in layers:
errors.append("Invalid Layer! ")
valid = False
if origin not in origins:
errors.append("Invalid Origin! ")
valid = False
try:
posX = int(posX)
posY = int(posY)
except:
errors.append("Invalid Position! ")
valid = False
if framecount is not None and framerate is not None and loop is not None:
if not isinstance(framecount, int) or not isinstance(framerate, int):
errors.append("Invalid Frame count or Frame rate! ")
valid = False
if loop not in ["LoopForever","LoopOnce"]:
errors.append("Invalid Type! ")
valid = False
if valid:
self.props.append("Animation,%s,%s,%s,%s,%s,%s,%s,%s" % (layer, origin, path, posX, posY, framecount, framerate, loop))
else:
self.props = errors
else:
if valid:
self.props.append("Sprite,%s,%s,\"%s\",%s,%s" % (layer, origin, path, posX, posY))
else:
self.props = errors
def fade(self, easing,startTime,endTime,startFade,endFade,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
except:
errors.append("Invalid Time! ")
valid = False
try:
startFade = float(startFade)
endFade = float(endFade)
except:
errors.append("Invalid Fade! ")
valid = False
if valid:
if loop:
self.props.append("\n F,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startFade, endFade))
else:
self.props.append("\n F,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startFade, endFade))
else:
self.props.append("\n" + "".join(errors))
def move(self, easing,startTime,endTime,startmoveX,startmoveY,endmoveX,endmoveY,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
except:
errors.append("Invalid Time! ")
valid = False
if not isinstance(startmoveX, int) or not isinstance(startmoveY, int) or not isinstance(endmoveX, int) or not isinstance(endmoveY, int):
errors.append("Invalid Move! ")
valid = False
if valid:
if loop:
self.props.append("\n M,%s,%s,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startmoveX, startmoveY, endmoveX, endmoveY))
else:
self.props.append("\n M,%s,%s,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startmoveX, startmoveY, endmoveX, endmoveY))
else:
self.props.append("\n" + "".join(errors))
def moveX(self, easing,startTime,endTime,startmoveX,endmoveX,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
startmoveX = int(startmoveX)
endmoveX = int(endmoveX)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
if loop:
self.props.append("\n MX,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startmoveX, endmoveX))
else:
self.props.append("\n MX,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startmoveX, endmoveX))
else:
self.props.append("\n" + "".join(errors))
def moveY(self, easing,startTime,endTime,startmoveY,endmoveY,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
startmoveY = int(startmoveY)
endmoveY = int(endmoveY)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
if loop:
self.props.append("\n MY,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startmoveY, endmoveY))
else:
self.props.append("\n MY,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startmoveY, endmoveY))
else:
self.props.append("\n" + "".join(errors))
def scale(self, easing,startTime,endTime,startScale,endScale,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
startScale = float(startScale)
endScale = float(endScale)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
if loop:
self.props.append("\n S,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startScale, endScale))
else:
self.props.append("\n S,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startScale, endScale))
else:
self.props.append("\n" + "".join(errors))
def vecscale(self, easing,startTime,endTime,startscaleX,startscaleY,endscaleX,endscaleY,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
startscaleX = float(startscaleX)
endscaleX = float(endscaleX)
startscaleY = float(startscaleY)
endscaleY = float(endscaleY)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
if loop:
self.props.append("\n V,%s,%s,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startscaleX, startscaleY, endscaleX, endscaleY))
else:
self.props.append("\n V,%s,%s,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startscaleX, startscaleY, endscaleX, endscaleY))
else:
self.props.append("\n" + "".join(errors))
def rotate(self, easing,startTime,endTime,startRotate,endRotate,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
startRotate = float(startRotate)
endRotate = float(endRotate)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
if loop:
self.props.append("\n R,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startRotate, endRotate))
else:
self.props.append("\n R,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startRotate, endRotate))
else:
self.props.append("\n" + "".join(errors))
def color(self, easing,startTime,endTime,startR,startG,startB,endR,endG,endB,loop = False):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
startR = int(startR)
startG = int(startG)
startB = int(startB)
endR = int(endR)
endG = int(endG)
endB = int(endB)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
if loop:
self.props.append("\n C,%s,%s,%s,%s,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startR, startG, startB, endR, endG, endB))
else:
self.props.append("\n C,%s,%s,%s,%s,%s,%s,%s,%s,%s" % (easing, startTime, endTime, startR, startG, startB, endR, endG, endB))
else:
self.props.append("\n" + "".join(errors))
def para(self, easing,startTime,endTime,parameter):
valid = True
errors = ""
if check_easing(easing):
errors.append("Invalid Easing! ")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
except:
errors.append("Invalid Arguments! ")
valid = False
if parameter not in ["H", "V", "A"]:
errors.append("Invalid Parameter!")
valid = False
if valid:
self.props.append("\n P,%s,%s,%s,%s" % (easing, startTime, endTime, parameter))
else:
self.props.append("\n" + "".join(errors))
def loop(self, startTime,loopCount):
valid = True
errors = ""
try:
startTime = int(startTime)
loopCount = int(loopCount)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
self.props.append("\n L,%s,%s" % (startTime, loopCount))
else:
self.props.append("\n" + "".join(errors))
def trigger(self, trigger, startTime, endTime):
valid = True
errors = ""
if type(trigger) is not str:
errors.append("Invalid Trigger!")
valid = False
try:
startTime = int(startTime)
endTime = int(endTime)
except:
errors.append("Invalid Arguments! ")
valid = False
if valid:
self.props.append("\n T,%s,%s,%s" % (trigger,startTime, endTime))
else:
self.props.append("\n" + "".join(errors))
@classmethod
def end(cl,osbfile):
if os.path.isfile(osbfile):
os.remove(osbfile)
with open(osbfile, "a") as text:
text.write("[Events]\n//Background and Video events\n//Storyboard Layer 0 (Background)\n")
for val in cl.back_obj:
text.write("%s\n" % "".join(val.props))
text.write("//Storyboard Layer 1 (Fail)\n")
for val in cl.fail_obj:
text.write("%s\n" % "".join(val.props))
text.write("//Storyboard Layer 2 (Pass)\n")
for val in cl.pass_obj:
text.write("%s\n" % "".join(val.props))
text.write("//Storyboard Layer 3 (Foreground)\n")
for val in cl.fore_obj:
text.write("%s\n" % "".join(val.props))
text.write("//Storyboard Sound Samples")
def spectrum(wav_file,mi,mx,har,start,end,posX,posY,layer,origin,gap=0,arrange="",radius=30,sinheight=6.1):
frame_rate, snd = wavfile.read(wav_file)
sound_info = snd[:,0]
spectrum, freqs, t, im = plt.specgram(sound_info,NFFT=1024,Fs=frame_rate,noverlap=5,mode='magnitude')
n = 0
rotation = 6.2831
sinpos = {}
cirpos = {}
if arrange is "sinus":
sinpos = sinus(har,radius,sinheight)
for i in range(har):
cirpos[i] = 0
elif arrange is "circle":
gap = 0
sinpos, cirpos = circle(har,radius)
rotation /= har
else:
for i in range(har):
sinpos[i] = 0
for i in range(har):
cirpos[i] = 0
maximum = plt.amax(spectrum)
minimum = plt.amin(spectrum)
position = 0
while n < har:
lastval = ((spectrum[n][0]-minimum)/(maximum - minimum))*(mx-mi)+mi
lastval = math.ceil(lastval*1000)/1000
lasttime = int(round(t[0]*1000))
spect.append(osbject("bar.png",layer,origin,posX+position*gap+int(round(float(cirpos[n]))),posY+int(round(float(sinpos[n])))))
position += 1
if arrange is "circle":
spect[n].rotate(0,start,start,math.ceil((1.5707+n*rotation)*1000)/1000,math.ceil((1.5707+n*rotation)*1000)/1000)
for index,power in enumerate(spectrum[n]):
power = ((power-minimum)/(maximum - minimum))*(mx-mi)+mi
power = math.ceil(power*1000)/1000
if power == lastval or int(round(t[index]*1000)) < start or int(round(t[index]*1000)) > end or index % 2 is not 0:
lasttime = int(round(t[index]*1000))
continue
else:
spect[n].vecscale(0,lasttime,int(round(t[index]*1000)),1,lastval,1,power)
lastval = power
lasttime = int(round(t[index]*1000))
n += 1