Doraemon Theme Song (An align&mix demo)

This is a demo showing how to use ScoreDraft’s dynamic tempo mapping function to align and mix generated content with imported content. In this case, we will generate the singing track using 三色あやか voicebank, then align and mix the generated track with an imported instrumental track.

Doraemon Theme Song is one of the most famous anime songs authored by 菊池俊辅.

Here is the instrumental music we will use as a source material:

We first write down singing sequence, and generate the singing track at tempo 120bpm.


#!/usr/bin/python3

import ScoreDraft
from ScoreDraft.Notes import *

def faS(octave=5, duration=48):
    return note(octave,Freqs[6],duration)

FreqsEb=[f*Freqs[3] for f in Freqs]
Freqs[:]=FreqsEb

# 三色あやか 連続音V2.0: https://bowlroll.net/file/69898
singer= ScoreDraft.Ayaka2_UTAU()
singer.setLyricConverter(ScoreDraft.JPVCVConverter)

buf=ScoreDraft.TrackBuffer()

seq=[('こ', so(4,18), 'ん', so(4,18), 'な', do(5,12), 'こ', do(5,36), 'と', mi(5,12), 'い', la(5,36), 'い', mi(5,12), 'な', so(5,36)), BL(12)]
seq+=[('で', so(5,36), 'き', la(5,12), 'た', so(5,36), 'ら', mi(5,12), 'い', fa(5,36), 'い', mi(5,12), 'な', re(5,36)), BL(12)]

line=('あ', la(4,18), 'ん', la(4,18), 'な', re(5,12), 'ゆ', re(5,36), 'め', fa(5,12), 'こ', la(5,18), 'ん',ti(5,18), 'な', ti(5,12), 'ゆ', la(5,36), 'め', so(5,12))
line+=('い', fa(5,36), BL(12), 'ば', fa(5,36), 'い', mi(5,12), 'あ', la(4,24), 'る', ti(4,48), 'け', do(5,24), 'ど', re(5,144))
seq+=[line, BL(48)]

seq+=[('み', so(4,18), 'ん', so(4,18), 'な', do(5,12), 'み', do(5,18),'ん', do(5,18), 'な', mi(5,12), 'み', la(5,36), 'ん', mi(5,12), 'な', so(5,36)), BL(12)]
seq+=[('か', so(5,36), 'な', la(5,12), 'え', so(5,36), 'て', mi(5,12), 'く', fa(5,36), 'れ', mi(5,12), 'る', re(5,36)), BL(12)]

line=('ふ', la(4,36), 'し', re(5,12), 'ぎ', re(5,36), 'な', fa(5,12), 'ぽ', la(5,18),ti(5,18), BL(12), 'け', la(5,36), 'で', so(5,12))
line+=('か', fa(5,36), 'な', fa(5,12), 'え', mi(5,36), 'て', re(5,12), 'く', ti(4,24), do(5,24), 'れ', re(5,48), 'る', do(5,144))
seq+=[line, BL(48)]

seq+=[('そ',la(5,48), 'ら', la(5,36), 'お', so(5,12), 'じ', fa(5,12), so(5,12), 'ゆ', la(5,24), 'に', so(5,36)), BL(12)]
seq+=[('と',re(5,36), 'び', mi(5,12), 'た', faS(5,36), 'い', re(5,12), 'な', so(5,72)), BL(24)]

seq+=[('は', mi(5,12)+ti(5,12)+so(5,0), 'い', so(5,24)+mi(5,0) ), BL(72), ('た', re(5,12),mi(5,0), 'け', so(5,12)+mi(5,0), 'こ',ti(5,36),'ぽ', so(5,12)+mi(5,0), 'た',mi(5,72)+do(5,0)), BL(24), BL(96)]

seq+=[('あ', la(5,24), 'ん', la(5,24), 'あ', so(5,24), 'ん', so(5,24), 'あ', fa(5,36), 'ん', fa(5,36)), BL(24)]
seq+=[('と', re(5,36), BL(12), 'て', ti(5,36), 'も', la(5,12), 'だ', so(5,36), 'い', la(5,12), 'す', so(5,24), 'き', fa(5,24))]
seq+=[BL(48), ('ど', so(5,36), 'ら', la(5,12), 'え', mi(5,72), 'も', re(5,24), 'ん', do(5,144)), BL(48)]

singer.sing(buf, seq, 120)

ScoreDraft.WriteTrackBufferToWav(buf,'Doraemon.wav')

With the instrumental music (Doraemon_inst.wav) opened in Audacity, we can identify some land-marker time points, let’s keep a record of these time points in PCM sample unit.

Using the land-marker data, we can insert code to create a tempo map. Using the tempo map, we can generate the singing track at instrument aligned position. Then we can mix the singing track with instrumental track. Here goes the full code:


#!/usr/bin/python3

import ScoreDraft
from ScoreDraft.Notes import *

def faS(octave=5, duration=48):
    return note(octave,Freqs[6],duration)

def printTempos(tempo_map):
    print([ (tempo_map[i][0]-tempo_map[i-1][0])/48/(tempo_map[i][1]-tempo_map[i-1][1])*44100*60 for i in range(1, len(tempo_map))])

FreqsEb=[f*Freqs[3] for f in Freqs]
Freqs[:]=FreqsEb

# 三色あやか 連続音V2.0: https://bowlroll.net/file/69898
# Without CUDA, please use something like Ayaka2_UTAU
singer= ScoreDraft.Ayaka2_UTAU()
singer.setLyricConverter(ScoreDraft.JPVCVConverter)

buf=ScoreDraft.TrackBuffer()

tempo_map=[(0, 719035)]

seq=[('こ', so(4,18), 'ん', so(4,18), 'な', do(5,12), 'こ', do(5,36), 'と', mi(5,12), 'い', la(5,36), 'い', mi(5,12), 'な', so(5,36)), BL(12)]
seq+=[('で', so(5,36), 'き', la(5,12), 'た', so(5,36), 'ら', mi(5,12), 'い', fa(5,36), 'い', mi(5,12), 'な', re(5,36)), BL(12)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 892899)]

line=('あ', la(4,18), 'ん', la(4,18), 'な', re(5,12), 'ゆ', re(5,36), 'め', fa(5,12), 'こ', la(5,18), 'ん',ti(5,18), 'な', ti(5,12), 'ゆ', la(5,36), 'め', so(5,12))
line+=('い', fa(5,36), BL(12), 'ば', fa(5,36), 'い', mi(5,12), 'あ', la(4,24), 'る', ti(4,48), 'け', do(5,24), 'ど', re(5,144))
seq+=[line, BL(48)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 1151320)]

seq+=[('み', so(4,18), 'ん', so(4,18), 'な', do(5,12), 'み', do(5,18),'ん', do(5,18), 'な', mi(5,12), 'み', la(5,36), 'ん', mi(5,12), 'な', so(5,36)), BL(12)]
seq+=[('か', so(5,36), 'な', la(5,12), 'え', so(5,36), 'て', mi(5,12), 'く', fa(5,36), 'れ', mi(5,12), 'る', re(5,36)), BL(12)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 1324831)]

line=('ふ', la(4,36), 'し', re(5,12), 'ぎ', re(5,36), 'な', fa(5,12), 'ぽ', la(5,18),ti(5,18), BL(12), 'け', la(5,36), 'で', so(5,12))
line+=('か', fa(5,36), 'な', fa(5,12), 'え', mi(5,36), 'て', re(5,12), 'く', ti(4,24), do(5,24), 'れ', re(5,48), 'る', do(5,144))
seq+=[line, BL(48)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 1583921)]

seq+=[('そ',la(5,48), 'ら', la(5,36), 'お', so(5,12), 'じ', fa(5,12), so(5,12), 'ゆ', la(5,24), 'に', so(5,36)), BL(12)]
seq+=[('と',re(5,36), 'び', mi(5,12), 'た', faS(5,36), 'い', re(5,12), 'な', so(5,72)), BL(24)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 1761069)]

seq+=[('は', mi(5,12)+ti(5,12)+so(5,0), 'い', so(5,24)+mi(5,0) ), BL(72), ('た', re(5,12),mi(5,0), 'け', so(5,12)+mi(5,0), 'こ',ti(5,36),'ぽ', so(5,12)+mi(5,0), 'た',mi(5,72)+do(5,0)), BL(24), BL(96)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 1934081)]

seq+=[('あ', la(5,24), 'ん', la(5,24), 'あ', so(5,24), 'ん', so(5,24), 'あ', fa(5,36), 'ん', fa(5,36)), BL(24)]
seq+=[('と', re(5,36), BL(12), 'て', ti(5,36), 'も', la(5,12), 'だ', so(5,36), 'い', la(5,12), 'す', so(5,24), 'き', fa(5,24))]
seq+=[BL(48), ('ど', so(5,36), 'ら', la(5,12), 'え', mi(5,72), 'も', re(5,24), 'ん', do(5,144)), BL(48)]

tempo_map+=[(ScoreDraft.TellDuration(seq), 2285364)]

printTempos(tempo_map)

#singer.sing(buf, seq, 120)
singer.sing(buf, seq, tempo_map)

bufBG=ScoreDraft.TrackBuffer()
ScoreDraft.ReadTrackBufferFromWav(bufBG,"Doraemon_inst.wav")

bufMix=ScoreDraft.TrackBuffer()
ScoreDraft.MixTrackBufferList(bufMix, [buf,bufBG])

ScoreDraft.WriteTrackBufferToWav(bufMix,'Doraemon.wav')

Final result:

About the Author

Leave a Reply

Your email address will not be published. Required fields are marked *