start.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # encoding: utf-8
3 
4 """
5 Created by Yading Song on 2013-04-21 for Music Hack Day in Paris
6 Copyright (c) 2013 . All rights reserved.
7 """
8 
9 #import soundcloud
10 #import musixmatch
11 #import musixmatch.ws
12 
13 import json
14 import os,sys,optparse,signal,time,math
15 import cherrypy as cp
16 import numpy
17 import sys
18 sys.path.append('/usr/local/lib/python2.7/site-packages')
19 from cherrypy.lib import static
20 import subprocess as sp
21 from subprocess import Popen as spopen
22 
23 import time
24 import random
25 """"*********************************************************************************"""
26 
27 from xml.dom import minidom
28 import urllib2 #call url function
29 import os
30 import sys
31 import cPickle
32 
33 import pyechonest # import echonest API
34 from pyechonest import artist, catalog, config, playlist # How it works instead of pyechonest
35 
36 from echonest.remix import audio, modify
37 
38 # echonest API for pitch shifting
39 config.ECHO_NEST_API_KEY="SFXNKMTRAZ3ULHK6U "
40 
41 # musiXmatch API key
42 apikey = '8496dd1c715c69a74ef9fcde1716cf4a'
43 
44 
45 # 7 digital API key
46 DIGITAL7_API_KEY = '7dbpa63h3y3d'
47 
48 
49 usage = """
50 Usage:
51  python beatshift.py <input_filename> <output_filename>
52 Exampel:
53  python beatshift.py CryMeARiver.mp3 CryMeAShifty.mp3
54 """
55 
56 
57 
58 # this is just a parser for command line options for the server.
59 op = optparse.OptionParser()
60 op.add_option('-u', '--user', action="store", dest="USER", default="devel", type="str")
61 options, args = op.parse_args()
62 CONFIG_FILE = "%(USER)s.cfg" %options.__dict__
63 
64 if not os.path.isfile(CONFIG_FILE) :
65  print >> sys.stderr, "Config file not found: %s" %CONFIG_FILE
66  sys.exit(-1)
67 
68 # This is the server side of the actual Web-application
70 
71  def __init__(self):
72  self.inputs = []
73 
74  def index(self):
75  return ""
76 
77 
78  @cp.expose
79  def receiveinput(self, userinput):
80  # type in the title of the song you like
81  print "\n\n >>>The user entered the text: %(userinput)s\n\n" %locals()
82 
83  #lyrics = musixmatch.ws.track.lyrics.get('Baby',apikey=apikey)
84 
85  html_head = '''<!DOCTYPE html> <html lang="en"> <head><meta charset="utf-8"><title>BrutalizeMe</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""><meta name="author" content=""><!-- Le styles --> <link href="css/bootstrap.css" rel="stylesheet"><style type="text/css">body { padding-top: 20px; padding-bottom: 40px;} /* Custom container */ .container-narrow { margin: 0 auto; max-width: 700px;} .container-narrow > hr { margin: 30px 0;} /* Main marketing message and sign up button */.jumbotron { margin: 60px 0; text-align: center;} .jumbotron h1 { font-size: 72px; line-height: 1; } .jumbotron .btn { font-size: 21px; padding: 14px 24px; } /* Supporting marketing content */ .marketing { margin: 60px 0;} .marketing p + h4 { margin-top: 28px;} .input { border: 1px solid #006;background: #ffc;} </style> <link href="css/bootstrap-responsive.css" rel="stylesheet"> <!-- Fav and touch icons --> <link rel="shortcut icon" href="../assets/ico/favicon.ico"> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../assets/ico/apple-touch-icon-144-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../assets/ico/apple-touch-icon-114-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../assets/ico/apple-touch-icon-72-precomposed.png"><link rel="apple-touch-icon-precomposed" href="../assets/ico/apple-touch-icon-57-precomposed.png"> <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css"/> <link rel="stylesheet" href="css/styles.css"/> <script src="js/jquery.min.js"></script> <script src="http://code.jquery.com/ui/1.9.1/jquery-ui.js"></script><script type="text/javascript" src="js/main.js"></script> <script type="text/javascript" src="js/infoSongs.js"></script><script type="text/javascript" src="js/genre.js"></script></head><body><div id="dz-root"></div><div class="container-narrow"><hr><div class="jumbotron"> <h1>Results</h1> '''
86 
87  content = '''<div style="text-align:center"> <p> You have chosen <b> %s </b> music </p></div>''' %userinput
88  html_tail = '''</div><div style="margin:0 auto;width:75%;text-align:center"><script type="text/javascript" src="http://mediaplayer.yahoo.com/js"></script><br /> <a href="javascript: history.go(-1)">Back</a> </div></body> </html>'''
89  audio_url = ""
90 
91  #(tracktitle, trackid) = get_trackid_from_text_search(userinput,'Justin Bieber')
92  (tracktitle, trackid) = get_trackid_from_text_search(userinput,'')
93 
94  audio_url = get_preview_from_trackid(trackid)
95 
96  content = content + '''<div style="text-align:center"><p><a href=" %s ">''' % audio_url + '''<b> %s </b>''' % userinput
97 
98  file_name = tracktitle + u'.mp3'
99  file_name = file_name.replace(u'/', u' ')
100 
101  #file_name = t.title + u'.mp3'
102  # download_path = os.path.join(file_path, file_name)
103 
104  file_name = "Baby.mp3"
105  # download the song in the same path folder
106  path_name = './' + file_name
107  mp3 = download_file(audio_url, path_name)
108 
109  os.system('ffmpeg -i Baby.mp3 -ac 1 Baby.wav')
110  os.system('./sonic-annotator-0.7-osx-x86_64/sonic-annotator -d vamp:mtg-melodia:melodia:melody Baby.wav -w csv --csv-one-file baby.txt --csv-separator " " ')
111 
112 
113  print "Pitch Shifting Done"
114 
115  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"step1('Baby.wav');exit;\" ")
116  #os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"step1('Baby.wav');exit;\" ")
117  print "Melody"
118 
119  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"step2('Baby.wav');exit;\" ")
120  #os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"step2('Baby_ps12.wav');exit;\" ")
121  print "Instrument"
122  #os.system('/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r "mcc -m filename.m;exit;"')
123 
124  print "Done STEP 1"
125 
126  # light version
127  pitchshifting5('melody.wav','melody_ps5.wav')
128  print "pitch shifting 5"
129  # heaven version
130  pitchshifting12('melody.wav','melody_ps12.wav')
131 
132 
133  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"step3('melody_ps5.wav');exit;\"")
134  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"step3_heavy('melody_ps12.wav');exit;\"")
135  print "Step 3"
136 
137  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"fix_offset('melody.wav','ysbaby_voice_light.wav');exit;\"")
138  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"fix_offset('melody.wav','ysbaby_voice_heavy.wav');exit;\"")
139 
140  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"final_mix('ysbaby_voice_light.wav','instrumental.wav');exit;\"")
141  os.system("/Applications/MATLAB_R2012b.app/bin/matlab -nojvm -nosplash -nodisplay -r \"final_mix_heavy('ysbaby_voice_heavy.wav','instrumental.wav');exit;\"")
142 
143  lightaudio_url = 'light_' + tracktitle
144  midaudio_url = 'mid_' + tracktitle
145  heavyaudio_url = 'heavy_' + tracktitle
146 
147  content = content + '''<div style="text-align:center"><p><a href="MIX.wav">''' + '''<b> Light Version </b></div>'''
148  content = content + '''<div style="text-align:center"><p><a href="MIX_heavy.wav">''' + '''<b> Heavy Version </b>'''
149  #content = content + '''<p><a href=" %s ">''' % heavyaudio_url + '''<b> Heaven Version </b>'''
150 
151  return html_head, content, html_tail
152 
153  @cp.expose
154  def testpage(self):
155  return "<html> <body> You have accessed the test page </body> </html>"
156 
157 def pitchshifting5(input_filename, output_filename):
158  soundtouch = modify.Modify()
159  audiofile = audio.LocalAudioFile(input_filename)
160  beats = audiofile.analysis.beats
161  out_shape = (len(audiofile.data),)
162  out_data = audio.AudioData(shape=out_shape, numChannels=1, sampleRate=44100)
163 
164  for i, beat in enumerate(beats):
165  data = audiofile[beat].data
166  number = beat.local_context()[0] % 12
167  #new_beat = soundtouch.shiftPitchSemiTones(audiofile[beat], number*-1)
168  new_beat = soundtouch.shiftPitchSemiTones(audiofile[beat], -5)
169  out_data.append(new_beat)
170 
171  out_data.encode(output_filename)
172 
173 
174 def pitchshifting12(input_filename, output_filename):
175  soundtouch = modify.Modify()
176  audiofile = audio.LocalAudioFile(input_filename)
177  beats = audiofile.analysis.beats
178  out_shape = (len(audiofile.data),)
179  out_data = audio.AudioData(shape=out_shape, numChannels=1, sampleRate=44100)
180 
181  for i, beat in enumerate(beats):
182  data = audiofile[beat].data
183  number = beat.local_context()[0] % 12
184  #new_beat = soundtouch.shiftPitchSemiTones(audiofile[beat], number*-1)
185  new_beat = soundtouch.shiftPitchSemiTones(audiofile[beat], -12)
186  out_data.append(new_beat)
187 
188  out_data.encode(output_filename)
189 
190 
191 def url_call(url):
192  """
193  ***This method is from get_preview_url.py by Thierry Bertin-Mahieux***
194  Do a simple request to the 7digital API
195  We assume we don't do intense querying, this function is not robust
196  Return the answer as na xml document
197  """
198  stream = urllib2.urlopen(url)
199  xmldoc = minidom.parse(stream).documentElement
200  stream.close()
201  return xmldoc
202 
203 
204 def download_file(file_url, file_name):
205  # open the url
206  mp3file = urllib2.urlopen(file_url)
207 
208  # open the local file for writing
209  local_file = open(file_name, "wb")
210  # write to file
211  local_file.write(mp3file.read())
212  local_file.close()
213 
214 """"*********************************************************************************"""
215 
216 def get_trackid_from_text_search(title,artistname=''):
217  """
218  ***This method is from get_preview_url.py by Thierry Bertin-Mahieux***
219  Search for an artist + title using 7digital search API
220  Return None if there is a problem, or tuple (title,trackid)
221  """
222  url = 'http://api.7digital.com/1.2/track/search?'
223  url += 'oauth_consumer_key='+DIGITAL7_API_KEY
224  query = title
225  if artistname != '':
226  query = artistname + ' ' + query
227  query = urllib2.quote(query)
228  url += '&q='+query
229  xmldoc = url_call(url)
230  status = xmldoc.getAttribute('status')
231  if status != 'ok':
232  return None
233  resultelem = xmldoc.getElementsByTagName('searchResult')
234  if len(resultelem) == 0:
235  return None
236  track = resultelem[0].getElementsByTagName('track')[0]
237  tracktitle = track.getElementsByTagName('title')[0].firstChild.data
238  trackid = int(track.getAttribute('id'))
239  return (tracktitle,trackid)
240 
241 
243  """
244  ***This method is from get_preview_url.py by Thierry Bertin-Mahieux***
245  Ask for the preview to a particular track, get the XML answer
246  After calling the API with a given track id,
247  we get an XML response that looks like:
248 
249  <response status="ok" version="1.2" xsi:noNamespaceSchemaLocation="http://api.7digital.com/1.2/static/7digitalAPI.xsd">
250  <url>
251  http://previews.7digital.com/clips/34/6804688.clip.mp3
252  </url>
253  </response>
254 
255  We parse it for the URL that we return, or '' if a problem
256  """
257  url = 'http://api.7digital.com/1.2/track/preview?redirect=false'
258  url += '&trackid='+str(trackid)
259  url += '&oauth_consumer_key='+DIGITAL7_API_KEY
260  xmldoc = url_call(url)
261  status = xmldoc.getAttribute('status')
262  if status != 'ok':
263  return ''
264  urlelem = xmldoc.getElementsByTagName('url')[0]
265  preview = urlelem.firstChild.nodeValue
266  return preview
267 
268 
269 
270 """"*********************************************************************************"""
271 
272 
273 def getProcessPids(port,kill=False):
274  '''Get the pid of the offending Python process given a port after an unsuccessful restart.'''
275  print "Running lsof -i :"+str(port)," ...\n\n"
276  command = "lsof -i :"+str(port)
277  w = spopen(command,stdout=sp.PIPE,stderr=sp.PIPE,shell=True)
278  se = w.stderr.readlines()
279  result = w.stdout.readlines()
280  exitcode = w.wait()
281  if not result :
282  print "getProcessPid:: Unable to obtain process pid. (lsof returned nothing. exitcode: %s)" %str(exitcode)
283  return False
284  import pprint
285  pprint.pprint(result)
286 
287  # get heading:
288  ix = None
289  head = result[0].upper()
290  if 'PID' in head:
291  head = filter(lambda x: x != str(), head.split(' '))
292  head = map(lambda x: x.strip().replace(' ',''), head)
293  if 'PID' in head : ix = head.index('PID')
294  # get process pid
295  pids = []
296  for line in result :
297  if 'python' in line.lower() :
298  line = filter(lambda x: x != str(), line.split(' '))
299  line = map(lambda x: x.strip().replace(' ',''), line)
300  try :
301  if ix :
302  pids.append(int(line[ix]))
303  else:
304  numbers = filter(lambda x: x.isdigit(), line)
305  pids.append(int(numbers[0]))
306  except:
307  print 'Error parsing lsof results.'
308  return False
309  print 'Pids found: ',pids
310  # kill if specified
311  if kill :
312  pids_killed = []
313  import signal
314  for pid in pids:
315  print 'Killing process: ',pid
316  try :
317  os.kill(pid,signal.SIGKILL)
318  pids_killed.append(pid)
319  except :
320  print 'Failed: ',pid
321  if pids_killed :
322  print 'Processes killed:',pids_killed,' Waiting 10 seconds...'
323  import time
324  time.sleep(10)
325  return True
326  return False
327 
328 
329 def main(argv=None):
330 
331  # Configure and start
332 
333 
334  cp.config.update(CONFIG_FILE)
335  cp.config.update({'tools.staticdir.root': os.getcwd()})
336  cp.tree.mount(ServerExample(),script_name="/MusicHackParis",config=CONFIG_FILE)
337  port = int(cp.server.socket_port)
338  ip = cp.server.socket_host
339  print "Trying to bind: %(ip)s:%(port)s" %locals()
340  getProcessPids(port,kill=True)
341  cp.quickstart()
342 
343 if __name__ == "__main__":
344  main()
def getProcessPids(port, kill=False)
Definition: start.py:273
def url_call(url)
Definition: start.py:191
def get_trackid_from_text_search(title, artistname='')
Definition: start.py:216
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
def testpage(self)
Definition: start.py:154
def receiveinput(self, userinput)
Definition: start.py:79
def get_preview_from_trackid(trackid)
Definition: start.py:242
def pitchshifting12(input_filename, output_filename)
Definition: start.py:174
def main(argv=None)
Definition: start.py:329
def pitchshifting5(input_filename, output_filename)
Definition: start.py:157
int len
def index(self)
Definition: start.py:74
def download_file(file_url, file_name)
Definition: start.py:204
def __init__(self)
Definition: start.py:71