Loading...

The blog is being migrated and merged with multiple Imphenzia blogs so the format and content will be inconsistent for a while.

Secret to Composing Unique Music

In this post I will reveal how I created my unique style of music. With the large number of electronic artists making music today you could arguably question if anything is really unique but I still feel, and I often get feedback saying, that my music has a unique sound.

This unique sound may not be a special genre, but it could be a recognizable way that you combine instruments, how you arrange tracks, or how you play certain melodies. It may not even be possible to pinpoint exactly why it is unique. In my case I know I've succeeded when someone listens to my track and says "Yes - this is an Imphenzia track."

I started making music back in the early 1990s and as a method to learn I tried to copy the music of artists I admired. I repeatedly failed, many times over. I was disappointed at first but as time passed the failures turned out to be the key in creating my unique sound.

My advice to beginner artists (the target audience of this post) is to listen to the music you like and try to write down what you hear. Don’t look at midi data to find out exactly what notes are being played, exactly what instruments are used, exact melodies and note duration, etc.

Instead, use your ears and write down what you hear and what you like. Some of you are well educated in musical lingo while others may describe music in very generic terms. I, for example, listened to Astral Projection and I didn't (and still don't) know the proper musical terms for many things so I made very simple notes such as:

  • The lead instrument plays melodic scales and often transforms in sound from muffled to crisp.

  • One bassline plays a note on an interval offset to the kick drum. It also plays the same note many times over before transposing up or down.

  • Another bassline plays rapid notes in succession. I suspect every 16th. The notes alter octave up and down rapidly. One note may occasionally be transposed up a semi tone.

  • The percussion consists of a steady beating kick with a clap every other kick. A hihat plays in between every kick.

  • ...


After you listen to the music and once you've written down some notes covering what you hear, start up your music making software and try to create music based on your written notes. To begin with, try to recreate a particular part that you like and not a full length track. Listen to it for a while then refer back to your notes and make necessary adjustments.

Avoid listening to the original music you based your notes on while you compose your own music. This may cloud your creativity and influence you to make micro adjustments to get it to sound exactly like the original.

When you have a piece of music that you are happy with you may become discouraged when you finally do listen to the music that you compiled your notes from. The original track will, most probably, still sound much better and it is important at this stage to realize that it is perfectly okay to feel this way.

Repeat this process over and over with different tracks. Try to make a complete track from each attempt and not just fragments and clips. You'll find that your skills will improve with each attempt (with some exceptions =) and that you will favor some elements that reoccur as you progress. It is a fair chance that the elements you favor are what makes you unique.

My conclusion is as comic as it is simple: Create your unique sound by failing to copy others.

Here are some examples of what some of my "failed" attempts sounded like in the mid 90s and what my music sounds like today:

[soundcloud url="http://api.soundcloud.com/tracks/35761296" params="show_comments=true&auto_play=false&color=ff7700" width="100%" height="81" iframe="false" /]

[soundcloud url="http://api.soundcloud.com/tracks/35761451" params="show_comments=true&auto_play=false&color=ff7700" width="100%" height="81" iframe="false" /]

[soundcloud url="http://api.soundcloud.com/tracks/35761635" params="show_comments=true&auto_play=false&color=ff7700" width="100%" height="81" iframe="false" /]

[soundcloud url="http://api.soundcloud.com/tracks/35761912" params="show_comments=true&auto_play=false&color=ff7700" width="100%" height="81" iframe="false" /]

Scripts for Watermarking and Encoding Audio

I've decided to publish the scripts that I use to watermark and encode music audio files into MP3 and OGG files with meta tags. I hope this will help someone out there who needs to frequently watermark and/or encode audio files into WAV, MP3 and OGG files at different bit rates.

Maybe the simplest way to start off is to demonstrate how the scripts work with this video:


(Watch in HD at YouTube for better readability)


Click HERE TO DOWNLOAD the zip file containing the scripts.


Create_watermark.vbs Explained


This is a VBScript that will loop through a directory full of WAV audio files and mix them with watermark audio files. The script uses the free application Sound eXchange (SoX) to achieve this.

The script is also designed to take the duration of the audio file to be watermarked and apply a watermark with a suitable frequency.

Shorter audio files will be watermarked frequently and longer audio files will have less frequent watermarks to make it less annoying.

You can customize the watermark files to contain anything you want. If you want to change the name or format of them you'll have to modify the script appropriately.

You can download the entire script package and demo files at the top of this post, but if you wish to have a look at the script itself, here it is:
' #############################################################################
' IMPHENZIA SOUNDTRACK WATERMARKING SCRIPT http://soundtrack.imphenzia.com
' #############################################################################

' ## DESCRIPTION ##############################################################

' This VB script uses Sound eXchange (SoX) (http://sox.sourceforge.net) to
' create watermarked WAV files.

' Based on the duration of the WAV files you wish to watermark, the script
' will select a suitable frequency of the watermark. By default the following
' logic is applied:
' 0-5 second music file: watermark occurs every 2.5 seconds
' 5-15 second music file: watermark occurs every 5 seconds
' 15-30 second music file: watermark occurs every 10 seconds
' 30-1200 second music file: watermark occurs every 30 seconds
' > 20 minutes files are not supported - change the script if necessary.

' ## INSTRUCTIONS #############################################################

' 1. Put your original WAV files that you wish to watermarked in the
' subfolder "input-wav-originals"

' 2. Execute this script and it will create watermarked WAV files in the
' subfolder "output-wav-watermarked"

' ## CHANGING THE WATERMARK ###################################################

' The default watermark says the word "preview" at different intervals
' depending on the duration of the WAV file. You can change the watermark
' audio files but I recommend that you keep the name and ogg format of the
' watermark files so you don't have to modify the script.

' To change the watermark, replace the audio in the watermark files. Use
' trial and error to find a suitable volume (I recommend peaks at around
' -8 dB) and frequency of the watermark.

' ## LICENSE ##################################################################
' You're free to use this script and the watermark OGG files free of charge.
' If this script saves you a lot of time, a donation to [email protected]
' is very welcome =)

' SoX is a free application available at the URL in the description. This
' script is very dependent on the exact output SoX generates to read
' information so a version of SoX is included in the archive.

' (You may not sell the script or any of the files)

Dim source_folder, destination_folder
Dim watermark_folder, watermark_file, log_filename

' ## CUSTOMIZABLE VARIABLES ###################################################
source_folder = "input-wav-originals"
destination_folder = "output-wav-watermarked"
watermark_folder = "input-watermarks"
log_filename = "watermark-log.txt" ' Filename for log file (overwritten)
use_volume = true ' Watermark volume based on original

' You shouldn't need to edit any of the below script
' -----------------------------------------------------------------------------

Dim wshshell, filesys, folder, files_collection, filecount, filename
Dim outputfile, logoutput, duration, volume, volumedecimal, n

' ## Create Filesystem Objects
Set wshshell = WScript.CreateObject("WScript.Shell")
Set filesys = CreateObject("Scripting.FileSystemObject")
Set folder = filesys.GetFolder(source_folder & "\.")
Set files_collection = folder.Files
Set logoutput = filesys.OpenTextFile(log_filename, 2, True)

' ## Ensure that the output directory exists, if not then create it
if not filesys.FolderExists( destination_folder ) then _
filesys.CreateFolder destination_folder

' ## Create header in log file
logoutput.WriteLine("Source File, Source Duration, Watermark, " & _
"Source Amplitude, Watermark Amplitude")

' ## Loop through all original wav files
filecount = files_collection.Count
for each file in files_collection
filename = file.name
if lcase(right(filename,4))=".wav" then

' ## If a watermarked version does not exists, create one
if not filesys.FileExists( destination_folder & "\" & filename ) then

' ## Select appropriate watermarked file based on duration of source file
duration = CLng(runCMD("sox --info -s """ & _
source_folder & "\" & filename & """"))

if duration <= 220500 then _
watermark_file = watermark_folder & "\preview-0-5sec.ogg"
if duration > 220500 and duration <= 661500 then _
watermark_file = watermark_folder & "\preview-5-15sec.ogg"
if duration > 661500 and duration <= 1323000 then _
watermark_file = watermark_folder & "\preview-15-30sec.ogg"
if duration > 1323000 then _
watermark_file = watermark_folder & "\preview-30-1200sec.ogg"

' ## If volume is used, set volume based on amplitude of source wav file
if use_volume then
volume = runCMDAlt("sox """ & source_folder & "\" & filename & _
""" -n stat")
volume = mid(volume,123,8)
volumedecimal = CDbl(replace(volume, ".", ","))
else
volumedecimal = 1.0
end if

' ## Mix source wav file and watermark file to create a watermarked file
wshshell.Run "sox -m -v 1 """ & source_folder & "\" & filename & _
""" -v " & replace((volumedecimal*volumedecimal),",",".") & _
" """ & watermark_file & """ """ & destination_folder & _
"\" & filename & """ trim 0s " & duration & "s",0,true

' ## Write the action to log file
logoutput.WriteLine(source_folder & "\" & filename & "," & _
watermark_file & "," & replace((CDbl(duration)/44100),",",".") & "," & _
volume & "," & replace((volumedecimal*volumedecimal),",","."))

n=n+1
end if
end if
next

if n=0 then
wscript.echo "No Files Created " & vbCrLf & _
"If watermarked files already exist they are not recreated"
else
wscript.echo "Done! " & vbCrLf & n & " Watermarked File(s) Created "
end if

' Supporting function to capture the output of command line
function runCMD(strRunCmd)
Set objExec = wshshell.Exec(strRunCmd)
strOut = ""
Do While Not objExec.StdOut.AtEndOfStream
strOut = strOut & objExec.StdOut.ReadLine()
Loop
runCMD = strOut
End Function

' Supporting function to capture error output (workaround)
Function runCMDAlt(strRunCmd)
Set objExec = wshshell.Exec(strRunCmd)
strOut = ""
strOut = objExec.StdErr.ReadAll()
runCMDAlt = strOut
End Function

Encode_files.vbs Explained


This is a script that will loop through two directories, one full of original WAV audio/music files and one full of watermarked WAV files (if you previously ran the Create_watermarks.vbs script). As the script loops through all the available WAV files it will encode them into MP3 and OGG files and also update the meta tags containing information such as title, artist, publisher, copyright info, comments, URL, etc.

The script is designed so that you can enter meta tags and customize bit rate that you wish to encode your files with. Once you've got this running you can quickly re-encode your files into any bitrate or modify the meta tags without having to do it all manually.

You can download the entire script package and demo files at the top of this post, but if you wish to have a look at the script itself, here it is:
' #############################################################################
' IMPHENZIA SOUNDTRACK ENCODING SCRIPT http://soundtrack.imphenzia.com
' #############################################################################
' Version: 1.0

' ## DESCRIPTION ##############################################################

' This scripts encodes the wav files in the folder "input-wav-originals" and
' "output-wav-watermarked" into MP3 and OGG files.

' The script also creates meta tags for the MP3 and OGG files based on the
' source file name and additional customizable in this script.

' You can set the bitrate of the MP3 and OGG files in this script as well.

' ## INSTRUCTIONS #############################################################

' 1. Ensure that the WAV files in the "input-wav-originals" folder and the
' "output-wav-watermarked" folders contain files named according to the
' following naming standard:
' Arist Name_Song Name_Music Genre_Year
' Example:
' Imphenzia Soundtrack_Fog of War (Main Part Loop)_Orchestral_2011.wav

' 2. Customize the encoding bitrates for the original and watermarked MP3
' and OGG files (see CUSTOMIZABLE ENCODING BITRATES)

' 3. Customize the MP3 and OGG meta tags (see CUSTOMIZABLE MP3 and OGG TAGS)

' 4. Double click on the script to begin the encoding process. The script
' will create MP3 and OGG files in the appropriately named output folders.

' ## LICENSE ##################################################################

' You're free to use this script and the watermark OGG files free of charge.
' If this script saves you a lot of time, a donation to [email protected]
' is very welcome =)

' This script uses the following freeware and/or open source applications:
' lame.exe - http://www.mp3dev.org
' metamp3.exe - http://www.hydrogenaudio.org/forums/index.php?showtopic=49751
' oggenc.exe - http://www.rarewares.org/ogg-oggenc.php
' tag.exe - http://wiki.hydrogenaudio.org/index.php?title=Tag_(tagger)

' (You may not sell the script or any of the files)

Dim source_folder, source_watermarked_folder
Dim destination_mp3_original, destination_mp3_watermarked
Dim destination_ogg_original, destination_ogg_watermarked
Dim mp3_original_bitrate, mp3_watermarked_bitrate
Dim ogg_original_bitrate, ogg_watermarked_bitrate
Dim tag_encoder_name, tag_publisher_name, tag_copyright_name, tag_url
Dim tag_composer_name, tag_comment, tag_album, tag_watermarked_prefix

' ## CUSTOMIZABLE FOLDERS #####################################################
source_folder = "input-wav-originals"
source_watermarked_folder = "output-wav-watermarked"
destination_mp3_original = "output-mp3-original"
destination_mp3_watermarked = "output-mp3-watermarked"
destination_ogg_original = "output-ogg-original"
destination_ogg_watermarked = "output-ogg-watermarked"

' ## CUSTOMIZABLE ENCODING BITRATES ###########################################
mp3_original_bitrate = "160" ' Bitrate in kbps
mp3_watermarked_bitrate = "96" ' Bitrate in kbps
ogg_original_bitrate = "128" ' Bitrate in kbps
ogg_watermarked_bitrate = "64" ' Bitrate in kbps

' ## CUSTOMIZABLE MP3 and OGG TAGS#############################################
tag_encoder_name = "ENCODER NAME HERE"
tag_publisher_name = "PUBLISHER NAME HERE"
tag_copyright_name = "COPYRIGHT HOLDER NAME HERE"
tag_url = "http://YOUR URL HERE"
tag_composer_name = "COMPOSER NAME HERE"
tag_comment = "Encoded using script by http://soundtrack.imphenzia.com"
tag_album = "TEXT FOR ALBUM FIELD HERE"
tag_watermarked_prefix = "Preview: "

' You shouldn't need to edit any of the below script
' -----------------------------------------------------------------------------

' Ensure that cscript is executed instead of wscript - otherwise status
' messages will appear in popups instead of console window.

If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
strPath = Wscript.ScriptFullName
strCommand = "%comspec% /k cscript """ & strPath & """"
Set objShell = CreateObject("Wscript.Shell")
objShell.Run(strCommand), 1, True
Wscript.Quit
End If

Dim wshshell, filesys, folder, files_collection, filecount, filename
Dim mp3counter, oggcounter, outputfile
Dim tag_artist, tag_title, tag_genre, tag_year
oggcounter = 0
mp3counter = 0

wscript.echo "Begin encoding process."

Set wshshell = WScript.CreateObject("WScript.Shell")
Set filesys = CreateObject("Scripting.FileSystemObject")

' ## Ensure that the output directories exists, if not then create them
if not filesys.FolderExists( destination_mp3_original ) then _
filesys.CreateFolder destination_mp3_original
if not filesys.FolderExists( destination_ogg_original ) then _
filesys.CreateFolder destination_ogg_original
if not filesys.FolderExists( destination_mp3_watermarked ) then _
filesys.CreateFolder destination_mp3_watermarked
if not filesys.FolderExists( destination_ogg_watermarked ) then _
filesys.CreateFolder destination_ogg_watermarked

' ## Encode Original (non-watermarked) files ##################################
Set folder = filesys.GetFolder(source_folder & "\.")
Set files_collection = folder.Files
filecount = files_collection.Count

for each file in files_collection
' ## Only process WAV files
filename = file.name
if lcase(right(filename,4))=".wav" then

' ## Set tags based on the filename
' ## Source File Name Format: Artist Name_Song Name_Music Genre_Year
tag_artist = GetParam(filename,0)
tag_title = GetParam(filename,1)
tag_genre = GetParam(filename,2)
tag_year = GetParam(filename,3)

' ## Create web friendly name for output file (artist-name-song-name)
outputfile = WebFriendlyName(GetParam(filename,0) & " - " & _
GetParam(filename,1) ,0,0)

' ## MP3 Encoding ---------------------------------------------------------
' ## Create option string for MP3 meta tags
optstr = ""
optstr = optstr & " --title " & """" & tag_title & """"
optstr = optstr & " --artist " & """" & tag_artist & """"
optstr = optstr & " --comment " & """" & tag_comment & """"
optstr = optstr & " --genre " & """" & tag_genre & """"
optstr = optstr & " --year " & """" & tag_year & """"
optstr = optstr & " --album " & """" & tag_album & """"
optstr = optstr & " --user-url " & """" & tag_url & """"
optstr = optstr & " --frame TCOM:" & """" & tag_composer_name & """"
optstr = optstr & " --frame TENC:" & """" & tag_encoder_name & """"
optstr = optstr & " --frame TPUB:" & """" & tag_publisher_name & """"
optstr = optstr & " --frame TCOP:" & """" & tag_copyright_name & """"

' ## Only encode the MP3 file if it doesn't already exist
if not filesys.FileExists( destination_mp3_original & "\" & _
outputfile & ".mp3" ) then

wscript.echo "Encoding Original mp3 with a bitrate of " & _
mp3_original_bitrate & "kbps: " & vbCrLf & _
" " & outputfile & ".mp3" & vbCrLf

' ## Use Lame to encode the mp3 file
wshshell.Run "lame.exe -b " & mp3_original_bitrate & _
" -c """ & source_folder & "\" & filename & """ " & _
"""" & destination_mp3_original & "\" & outputfile & _
".mp3""",0,true

' ## Use Metamp3 to create the mp3 tag
wshshell.Run "metamp3.exe " & optstr & " """ & _
destination_mp3_original & "\" & outputfile & _
".mp3""",0,true
mp3counter = mp3counter + 1

end if

' ## OGG Encoding ---------------------------------------------------------
' ## Create option string for OGG meta tags
optstr = ""
optstr = optstr & " --title " & """" & tag_title & """"
optstr = optstr & " --artist " & """" & tag_artist & """"
optstr = optstr & " --comment " & """" & tag_comment & """"
optstr = optstr & " --genre " & """" & tag_genre & """"
optstr = optstr & " --year " & """" & tag_year & """"
optstr = optstr & " --album " & """" & tag_album & """"
optstr = optstr & " -t URL=" & """" & tag_url & """"
optstr = optstr & " -t COMPOSER=" & """" & tag_composer_name & """"
optstr = optstr & " -t PUBLISHER=" & """" & tag_publisher_name & """"
optstr = optstr & " -t COPYRIGHT=" & """" & tag_copyright_name & """"

' ## Only encode the OGG file if it doesn't already exist
if not filesys.FileExists( destination_ogg_original & "\" &_
outputfile & ".ogg" ) then

wscript.echo "Encoding Original ogg with a bitrate of " & _
ogg_original_bitrate & "kbps: " & vbCrLf & _
" " & outputfile & ".ogg" & vbCrLf

' ## Use Oggenc to encode the ogg file
wshshell.Run "oggenc.exe -b " & ogg_original_bitrate & _
" --output=""" & destination_ogg_original & "\" & _
outputfile & ".ogg"" """ & source_folder & "\" & _
filename & """",0,true

' ## Use Tag to create the ogg tag
wshshell.Run "Tag.exe " & optstr & " """ & destination_ogg_original & _
"\" & outputfile & ".ogg""",0,true

oggcounter = oggcounter + 1
end if
end if
next

' ## Encode Watermarked files #################################################
Set folder = filesys.GetFolder(source_watermarked_folder & "\.")
Set files_collection = folder.Files
filecount = files_collection.Count

for each file in files_collection
' ## Only process WAV files
filename = file.name
if lcase(right(filename,4))=".wav" then

' ## Set tags based on the filename
' ## Source File Name Format: Artist Name_Song Name_Music Genre_Year
tag_artist = GetParam(filename,0)
tag_title = tag_watermarked_prefix & GetParam(filename,1)
tag_genre = GetParam(filename,2)
tag_year = GetParam(filename,3)

' ## Create web friendly name for output file (artist-name-song-name)
outputfile = WebFriendlyName(GetParam(filename,0) & " - " & _
GetParam(filename,1) ,0,0)

' ## MP3 Encoding ---------------------------------------------------------
' ## Create option string for MP3 meta tags
optstr = ""
optstr = optstr & " --title " & """" & tag_title & """"
optstr = optstr & " --artist " & """" & tag_artist & """"
optstr = optstr & " --comment " & """" & tag_comment & """"
optstr = optstr & " --genre " & """" & tag_genre & """"
optstr = optstr & " --year " & """" & tag_year & """"
optstr = optstr & " --album " & """" & tag_album & """"
optstr = optstr & " --user-url " & """" & tag_url & """"
optstr = optstr & " --frame TCOM:" & """" & tag_composer_name & """"
optstr = optstr & " --frame TENC:" & """" & tag_encoder_name & """"
optstr = optstr & " --frame TPUB:" & """" & tag_publisher_name & """"
optstr = optstr & " --frame TCOP:" & """" & tag_copyright_name & """"

' ## Only encode the MP3 file if it doesn't already exist
if not filesys.FileExists( destination_mp3_watermarked & "\" & _
outputfile & ".mp3" ) then

wscript.echo "Encoding Watermarked mp3 with a bitrate of " & _
mp3_watermarked_bitrate & "kbps: " & vbCrLf & _
" " & outputfile & ".mp3" & vbCrLf

' ## Use Lame to encode the mp3 file
wshshell.Run "lame.exe -b " & mp3_watermarked_bitrate & _
" -c """ & source_watermarked_folder & "\" & filename & """ " & _
"""" & destination_mp3_watermarked & "\" & outputfile & _
".mp3""",0,true

' ## Use Metamp3 to create the mp3 tag
wshshell.Run "metamp3.exe " & optstr & " """ & _
destination_mp3_watermarked & "\" & outputfile & _
".mp3""",0,true
mp3counter = mp3counter + 1

end if

' ## OGG Encoding ---------------------------------------------------------
' ## Create option string for OGG meta tags
optstr = ""
optstr = optstr & " --title " & """" & tag_title & """"
optstr = optstr & " --artist " & """" & tag_artist & """"
optstr = optstr & " --comment " & """" & tag_comment & """"
optstr = optstr & " --genre " & """" & tag_genre & """"
optstr = optstr & " --year " & """" & tag_year & """"
optstr = optstr & " --album " & """" & tag_album & """"
optstr = optstr & " -t URL=" & """" & tag_url & """"
optstr = optstr & " -t COMPOSER=" & """" & tag_composer_name & """"
optstr = optstr & " -t PUBLISHER=" & """" & tag_publisher_name & """"
optstr = optstr & " -t COPYRIGHT=" & """" & tag_copyright_name & """"

' ## Only encode the OGG file if it doesn't already exist
if not filesys.FileExists( destination_ogg_watermarked & "\" &_
outputfile & ".ogg" ) then

wscript.echo "Encoding Watermarked ogg with a bitrate of " & _
ogg_watermarked_bitrate & "kbps: " & vbCrLf & _
" " & outputfile & ".ogg" & vbCrLf

' ## Use Oggenc to encode the ogg file
wshshell.Run "oggenc.exe -b " & ogg_watermarked_bitrate & _
" --output=""" & destination_ogg_watermarked & "\" & _
outputfile & ".ogg"" """ & source_watermarked_folder & _
"\" & filename & """",0,true

' ## Use Tag to create the ogg tag
wshshell.Run "Tag.exe " & optstr & " """ & _
destination_ogg_watermarked & _
"\" & outputfile & ".ogg""",0,true

oggcounter = oggcounter + 1
end if
end if
next

' ## Finished - echo how many files were encoded
if mp3counter + oggcounter = 0 then
wscript.echo "No files were encoded."
wscript.echo "If the output files already exist they are not overwritten."
wscript.echo "Delete them first if you wish re-encode them."
else
wscript.echo "Encoding script reporting that all is done!"
wscript.echo mp3counter & " mp3 files and " & oggcounter & " ogg files encoded"
end if

' Supporting function that gets a parameter from a file name using the
' character _ as a delimiter
Function GetParam(thestring, theparam)
dim returnstring, currentparam
for i=1 to len(thestring)
if mid(thestring,i,1) = "_" then
currentparam=currentparam+1
else
if theparam = currentparam then
returnstring=returnstring + mid(thestring,i,1)
end if
end if
next
if lcase(right(returnstring,4)) = ".wav" then _
returnstring=left(returnstring,len(returnstring)-4)
GetParam = trim(returnstring)
end function

' Ugly supporting function that washes the file name to a "web friendly" file
' name... I would use regexp for this but VBScript is quite limited by default.
Function WebFriendlyName(filename, prefixlength, extlength)
WebFriendlyName = lcase(filename)
WebFriendlyName = right(WebFriendlyName , len(WebFriendlyName )-prefixlength)
WebFriendlyName = left(WebFriendlyName , len(WebFriendlyName )-extlength)
WebFriendlyName = replace(WebFriendlyName , " - ", "-")
WebFriendlyName = replace(WebFriendlyName , "[", "")
WebFriendlyName = replace(WebFriendlyName , "]", "")
WebFriendlyName = replace(WebFriendlyName , "(", "")
WebFriendlyName = replace(WebFriendlyName , ")", "")
WebFriendlyName = replace(WebFriendlyName , ".", "")
WebFriendlyName = replace(WebFriendlyName , " ", " ")
WebFriendlyName = replace(WebFriendlyName , " ", " ")
WebFriendlyName = replace(WebFriendlyName , " ", " ")
WebFriendlyName = replace(WebFriendlyName , " ", "-")
End Function

Does this save you a lot of time?











I've put hours and hours into creating these scripts and if you find them very useful and they save you a lot of time - please consider buying one of my digital albums at http://music.imphenzia.com/albums.html or make a donation to [email protected] =)

How I arranged the trance track Spirit Within You

Following some very positive feedback on the tutorial video on how I create trance music I also decided to dedicate today to make another tutorial of how I arranged the entire track Spirit Within You.

This video takes a detailed look at all the sections that form the track - such as the intro, the build up, the breakdown, the culmination, and the outro. It also explains how various instruments are introduced and modified during various stages of the track.

I am, by no means, saying that this is how you must make trance music - it's just at peek into how I arrange most of my tracks. When I started out making music in the 90s I found no tutorials like this and I'm hoping that this video can help some of you that are interested in making music.

Right then, here is the tutorial of how to arrange a trance song / track:


As usual, I use Cubase 5 and my trusted VST instruments Nexus2, VanGuard, and Sylenth1 - but this arrangement technique can be applied regardless of what software you use.

If this tutorial helps you out - I'd be happy to hear about it in the comments field =)

Good luck and happy music making!

How to make trance music tutorial

Today I decided to create a tutorial based on my latest trance track "Spirit Within You". It's a detailed look at a section of 15 measures of the track where I go through each and every instrument, what notes and chords are played, which presets are used, what VST instrument was used, etc. This should hopefully give you the foundation of percussion, bassline, melody,  filling effect - but it won't teach you how to arrange a full length track - that will come in another tutorial.

Have a look at the tutorial



What's in the video?


The video describes the following elements:

  • Percussion (drums) - kick, closed hihat, open hihat, claps, cymbals

  • First bassline (rapid 1/16 notes)

  • Second bassline  (offbeat 1/8 notes)

  • Cluster of 5 simultaneous leads for extreme atmosphere

  • Two trance gates for an even fuller effect

  • Pads for more euphoria

  • And a classic trance piano with delay end reverb


First the video lets you listen to the end result. Then I solo each instrument and describe what notes were played. You can also see exactly which presets are used in Nexus2, VanGuard, and Sylenth1. All presets, more or less, use the default settings and the default delay / reverb effects. Filter cutoff frequency is altered on a few instruments to create that classic morphing or transforming sound commonly found in trance. No additional, external, or invisible effects are applied.

In this video tutorial I use Cubase 5 as a sequencer - but the technique can be applied to any sequencer and VST instruments.

Since this video focuses on a cropped out section of the track, I plan to make another video showing how the track is arranged in terms of introducing various instruments, the intro, the chorus, the breakdown, the outro, etc.

If you like this video and, of course, if you like my music - please consider supporting Imphenzia by buying one of my albums in the album section (or on iTunes and other digital stores) - you can also gain Full Access to all Imphenzia tracks for high quality 320kbps MP3 and lossless FLAC files.

Virtual Instruments (VSTi) used

  • Groove Agent ONE (Cubase 5 drum machine)

  • ReFX Nexus2

  • ReFX VanGuard

  • LennarDigital Sylenth1


Presets used


All the presets are available in the retail version of each VSTi without the need for any expansions. The exception is the percussion since I just use various percussion samples.

ReFX Nexus2



  • Bass | BA Trancebass 19

  • Bass | Lazy Bass

  • Single Layer Leads | LD Detuned Lead 1

  • Epic Pads | PD Floating Away (with Trance Gate "TG" effect enabled)

  • Epic Pads | PD Tranceiver

  • Piano | PN Trancepiano



ReFX VanGuard



  • LD Corsten 01 MS

  • ARP Smuggler


LennarDigital Sylenth1



  • Bank 1 | LD Follow

  • Bank 2 | LD Rollback

  • Bank 1 | GAT Trancentral


Groove Agent ONE



  • Various drum samples accumulated over the years






Creating a low poly space ship in 3DS Max 2012

I decided to learn a bit more about modelling and texture mapping low poly 3D objects for games. My object of choice was a space ship and there are many skilled people out there who can do this ten times better than me, but at the same time I wanted to share my experience because you never know, someone might find it helpful =)

[caption id="attachment_313" align="alignright" width="620" caption="Figure 1: Render of final space ship"]Render of final space ship[/caption]

The space ship pictured above (Figure 1) is a render of my final object. It consists of 252 faces (polygons) and 249 vertices (intersecting points.) Additional detail is added by also creating a slightly higher detailed version (1900 faces and 2125 vertices) used to render a "normal map" which is effectively a bump map adding extra detail to the low polygon version. I'll explain how I did that as well.



Before getting started I'd also like to point out that this is not a full detailed click-by-click tutorial - it's rather a summary of how I went about modeling and texture mapping the object. It wasn't my intention to create a tutorial, it's just something I decided to do afterwards to document the major steps.

Starting with a box and using symmetry


I started by creating  a standard primitive Box object which I then converted to an Editable Poly. You can do this by right clicking on the box then selecting Convert To | Convert To Editable Poly.

To model the basic shape I changed selection method to "Polygon" so I could select the faces of the Editable Poly and then extrude and bevel them roughly shaping one side of a space ship. After some trial and error by repeatedly extruding faces and moving vertices I ended up with the basic shape of a space ship (Figure 2.)

[caption id="attachment_315" align="alignright" width="620" caption="Figure 2: Left side modeled by extruding faces / polygons of a primitive box"][/caption]

I realize that Figure 2 shows the result of many iterations of extruding and modifying the object but I don't have saved file from any previous version so I can't show the progress up until this point. If you are interested in a detailed tutorial - please leave a comment to this post and I'll make a detailed tutorial if there are enough requests =)

It's difficult to see what the shape will be by just looking at half a ship so I added the "Symmetry" modifier to mirror the X-axis of my ship. When you add the modifier you can move the gizmo to say where the mirror center should be and I modeled my ship so that the center of the ship is at the X-coordinate 0. Since the very center of my ship is at x = 0, I moved the symmetry gizmo to x = 0 which then displays the ship nicely (Figure 3) with both sides yet allowing you to work only on one side.

[caption id="attachment_318" align="alignright" width="620" caption="Figure 3: Symmetry modifier added to mirror X axis"][/caption]

[caption id="attachment_324" align="alignright" width="183" caption="Figure 4: Show End Result"][/caption]

When using the symmetry modifier it is important that you click "Show end result on/off toggle" (see Figure 4) on the Editable Poly to make sure the mirrored version of the ship is visible while modifying the Editable Poly. This is necessary since the symmetry modifier is above the Editable Poly in the modifier stack.

After some additional modeling, still only using extrude and bevel on faces, I ended up with a space ship shape that I was happy with (see Figure 5 below.)

[caption id="attachment_325" align="aligncenter" width="620" caption="Figure 5: Final Low Poly model"][/caption]

UVW Unwrapping and Texture Mapping


It's now time to paint the surfaces of the space ship (i.e. texture mapping) and that is done by first "unwrapping" the texture coordinates for the object. This is necessary so various surfaces of the space ship is represented by chunks of faces on a template image which can then be used as a reference to paint surfaces for the space ship, e.g. metal plates, dirt, stickers, and so forth.

The first thing I did was apply the "Unwrap UVW" modifier to my Editable Poly. Open the UV Editor by clicking the button "Open UV Editor...". The editor won't show anything useful to begin with, but click on the "Polygon" selector (see 1. in Figure 6) and then press Control + A to select all polygons.

[caption id="attachment_327" align="aligncenter" width="620" caption="Figure 6 - Unwrap UVW Editor"][/caption]

[caption id="attachment_328" align="alignright" width="300" caption="Figure 7: Flatten Mapping"][/caption]

When you have all the polygon selected (so they are highlighted in red) - go to Mapping | Flatten Mapping and set Face Angle Threshold to 60 and click OK. (Values between 45 and 60 degrees usually work where 45 will create more separate surfaces and and 60 will create fewer sets with larger chunks of polygons.)

This splits up all the faces into chunks (Figure 7) which are then distributed within a texture map square. Even though 3DS Max did a fairly good job at this we can't start painting on these just yet because there are some overlapping faces and they are not quite grouped the way we want them. We'll get back to that in a minute.

Checker Material


[caption id="attachment_331" align="alignright" width="290" caption="Figure 8: Checker Material"][/caption]

To make it easier to see what's going on I created a checker material in the 3DS Max material editor. In short, I did this by changing the Diffuse map of a material to "Checker" and setting the tiling values for U and V to 25 (see 1. in Figure 8) originally the value is 1 which would only create 4 squares in the checker material.)

Also click to "Show Shaded Material in Viewport" (see 2. in Figure 8.) This enables you to see how the texture map is applied to the object in the viewport rather than having to render the scene every time.

Finally, don't forget to assign the material to your Editable Poly (see 3. in Figure 8.) Once I applied the checker material onto my space ship it looked like as seen in Figure 9.

[caption id="attachment_332" align="aligncenter" width="620" caption="Figure 9: Checker Material on Space Ship"][/caption]

The great thing about the checker material is that you'll be able to see where texture will be stretched or compressed too much. You can see that the squares on the front of the wing are larger than on other parts of the space ship so this is something I had to address. Just by doing the Flatten Mapping 3DS Max has already performed a great job to split up the surfaces and as you can see the checker pattern flows quite nicely around the entire spaceship.

Break and Stitch the UV Map


When painting texture maps it is much simpler to have certain faces grouped together. A good example of this is the air intake of the engine (why a space ship have air intakes I don't know - but mine does anyway =). As you can see in Figure 10 I selected the polygons that form the inside of the air intake. I made the selection on the actual 3D object while having the UV Editor open because most of the time you won't be able to identify which polygons it is in the UV Editor. This is also why this needs to be performed - how would you know where to paint certain things if you don't know what part of the ship it is?

As I selected the polygons I then clicked Break (see 2. in Figure 10.) In this particular case it isn't actually necessary because all the polygons are already detached but often you'll find that the polygons you want are attached to other parts of the object. Make a habit of breaking the polygons before you stitch them together.

[caption id="attachment_335" align="aligncenter" width="620" caption="Figure 10: Break Polygons"][/caption]

Once detached, I moved one of the polygons to the side. Change the selection to Edge (see 1. in Figure 11) and select one of the edges of the polygon. When you select the edge, look among the other polygons and see if there is a blue edge on another polygon that you previously detached. If yes (as seen in figure 11 showing the blue edge on a polygon in the top right corner) these need to be stitched together by clicking on the blue stitch button (see 3. in Figure 11)

[caption id="attachment_336" align="aligncenter" width="620" caption="Figure 11: Stitch UV"][/caption]

Repeat the stitching process until you've stitched all the faces (in my case I stiched all the faces in the air intake. It was easy for me to figure out when I had stitched all the polygons together as you can see when I selected the bottom edge (see 1. in Figure 12) the top edge (see 2. in Figure 12) turned blue.

[caption id="attachment_337" align="aligncenter" width="620" caption="Figure 12: Stitch Complete"][/caption]

This is a slow and painful process and I performed it on both air intakes, the insides of the jet exhausts, the fins, the wings, and the cockpit.

When I was finally done, I rearranged all the polygons into the allocated square space representing the texture map. It's important to minimize the amount of unused space as you want to make sure the highest possible resolution is used for each part of the texture. There are 3rd Party helping tools, such as "Unfold 3D" and "UV Packer", that will simplify the packing process.

[caption id="attachment_339" align="alignright" width="300" caption="Figure 13: UVW Template"][/caption]

You should also go to the Display menu in the UV Editor and enable "Show Edge Distortion" every now and then. If you see any red or yellow lines it means that the edge is much shorter in the UV coordinates compared to the actual edge on your 3D object. Eliminate these red and yellow lines by moving the vertices until the lines turn green. If you don't do this, you may end up having distorted textures.

When done click the Tools menu in the UV Editor and select "Render UVW Template...".  I ended up with a template as seen in Figure 13.

At this point I knew what each group of polygons were located on the space ship.

Adding details to the low poly object using a normal map


There is a trick to make a low polygon object look like it's made out of many more polygons than it actually is. This is done by making a high detailed version of the object and then rendering it to a "normal" texture map which is then applied as a bump map to the low poly object.

To do this, I duplicated my space ship into a new object that I named "HighPoly". I hid my low poly space ship not to get confused as they still occupied the same space. I then continued the process of extruding, beveling, and chamfering parts of the ship to add details. Figure 13 shows what I ended up with.

[caption id="attachment_340" align="aligncenter" width="620" caption="Figure 14: High Poly Space Ship"][/caption]

Note: My "High Poly" space ship is still only 1900 polygons (compared to 252 polygons on my low poly version.) You can go absolutely crazy here with tens or hundreds of thousands of polygons - it won't affect the performance in the game and you can add a lot of details this way.

Once I was happy with my detailed version of the ship it was time to "Render To Texture" to create the normal map. I found a good YouTube tutorial for this so check it out and follow the steps to render your high poly version into a normal bump map:


[caption id="attachment_343" align="alignright" width="300" caption="Figure 15: Normal Map"][/caption]

The Normal Map I ended up with can be seen in Figure 15. I use a texture size of 1024x1024 pixels for all my texture maps. We'll apply this normal map to the low poly object in a minute.

Painting Diffuse and Specular Texture Maps


[caption id="attachment_345" align="alignright" width="300" caption="Figure 16: Diffuse Map"][/caption]

In Photoshop I loaded the UVW Template previously created (See Figure 13 earlier in this post.) I found some free textures (on CGTextures and Deviantart) that I used as a base for the Diffuse map (the actual texture of the space ship) and Specular map (shininess of the surfaces on the space ship.)

On the diffuse map (see Figure 16) I used grey metal textures as a base and I then added some shading, dirt, scratches, rivets, armor plate edges, text, and paint a simple paint job. The diffuse map is where you generally paint everything that you want to appear on your object.

[caption id="attachment_347" align="alignright" width="300" caption="Figure 17: Specular Map"][/caption]

I then also created a specular map (see Figure 17.) The purpose of the specular map is to describe how shiny certain areas of the space ship should be. Black is no shininess at all and white is as shiny as it can be. You can of course have shades of grey in between.

I used scratched metal surfaces covering most parts of the ship. The engines I made less shiny and also the cockpit as it reflected too much light for my liking (making it pure white with its flat surfaces.) I also made the rivets more shiny to make them standout somewhat.

[caption id="attachment_348" align="alignright" width="323" caption="Figure 18: Material"][/caption]

Creating the material


Now we have the diffuse map (Figure 16), the specular map (Figure 17), and the normal map (Figure 15.) Time to create the material. In the Material Editor I simply loaded the three images into the diffuse color, specular level, and bump slots as seen in Figure 18. I raised the Bump value from the original 30 to a value of 100.

Just to clarify - the material is assigned to the Low Poly object. The High Poly object can be hidden or deleted.

Final Render


This is what the final rendering of the object looks like:

Render of final space ship...and the specular shininess can best be previewed in this video clip:



The music in the video is available for licensing on my Imphenzia Soundtrack page. If you are here because you are making a space related game - you may also want to look at my site www.spacebox4096.com for space images with extremely high resolution to use as environment maps.

I hope you find some use out of this post - I'd be very happy if you drop a comment if this helped you out in any way =)

Thanks to the members of Maxforums.org for helping me with some useful tips, feedback, and links to tutorials.

Sound Forge script to create Seamless Loop

In my previous post I described how I create seamless music loops in Cubase and Sound Forge. I also mentioned that I have a Javascript for Sound Forge that I use to save time in performing the task to crop out the center third of the audio file along with fading the start and finish of the loop to remove any clicks at the loop point.

You can Download Seamless Loop Javascript for Sound Forge. Remember that you can't just magically rung this script on any old piece of audio to make a seamless loop of it - you need to follow the directions of the YouTube Tutorial to produce the audio file suitable for making a seamless loop.

Let's have a look at what the script does


Basically, I took the sample script that you get with Sound Forge that Crops and Fades a piece of audio. I then made the following alterations:
var smpLength : Int64 = Math.round(wnd.File.Length / 3);

The above line of code creates the variable smpLength, which is a 64 bit integer, to a third of the length of the audio file that is currently open and active in Sound Forge. I use the Math.round function to ensure it's a whole number as samples can't be decimals, it's either a sample or not =)
var asel : SfAudioSelection = new SfAudioSelection(smpLength, 
smpLength);

I then create the variable asel which is a new selection of audio. I use the arguments (smpLength, smpLength) for the constructor because I wan't it to start the selection one third into the audio file and I want the duration to also be a third. The script has now selected exactly the center third of the audio.
var ccFade : Int64 = 20;

We then set the variable ccFade to 20 which represents how many samples we want to fade. As you can see 20 samples is very little (0.00045 seconds if the sample rate is 44.1kHz) and this is because we just want to avoid the speaker having to abruptly jump to the start value other than 0 which would create and audible click.

Note: You may need to change ccFade depending on the music you are looping! For loud and aggressive music 20 samples is usually good, but for slow music such as sweeping strings and pads you may need around 100 samples. The reason for this is that 20 samples is still quite fast and it'll create a small percussive sound.

The rest of the script is pretty much the same as the Crop and Fade script I used as a base so it's a very small and simple modification.

You can also see the script in action in the YouTube tutorial video at 7:00.



Here is the entire script in clear text as well - or you can download it at the top of the post.
import System;
import System.Windows.Forms;
import SoundForge;

/*
Script: Seamless Loop Extractor
Author: Stefan Persson - Imphenzia Soundtrack - http://soundtrack.imphenzia.com

Run this script on an audio file were a piece of music is repeated 3 times exactly.
To create such an audio file in the first place copy a set of measures in your
sequencer software three times and export the audio from just the three sets of
measures. E.g. you want to loop 4 measures of music, make two adjacent copies of
the measures making it 12 measures in total. Export these 12 measures (no more and
no less) as an audio file.

The script will then crop out the center third of the audio file and make a very
short crossfade in the beginning and the end of the file to ensure that there is
no clicking at the loop points. What you should end up with is a perfect seamless
loop.

The crossfades are only 20 samples in length which should be inaudible for the ear
but without the crossfade the sample would start with a "click" as every audio
file should start and end at 0dB exactly.

NOTE! For slow pieces of music you may want to increase the variable ccFade from
20 to around 80 if there is an audible percussive click at the loop point.

(This script is based on the "Crop and Fade" sample script)
*/

public class EntryPoint {
public function Begin(app : IScriptableApp) {

var wnd = app.ActiveWindow;
if (null == wnd) return;

// We are interested in exactly one third of the samples in the center of the
// audio file, set smpLength to this value
var smpLength : Int64 = Math.round(wnd.File.Length / 3);

// Construct a new selection starting one third into the audio file with the
// duration of a third of the audio file
var asel : SfAudioSelection = new SfAudioSelection(smpLength, smpLength);

// Set the length of the fade to only 20.
// This can be changed and usually values between 10 and 100 will work, 10
// for aggressive music and 100 for very slow music.
var ccFade : Int64 = 20;

var file : ISfFileHost = wnd.File;

var fCancel = false;
var idUndo : int = file.BeginUndo("Crop and Fade");

file.CropAudio(asel.ccStart,asel.ccLength);
wnd.SelectionLength = 0; // remove the selection lest it confuse us.

file.DoEffect("Graphic Fade", "-6 dB exponential fade in",
new SfAudioSelection(0, ccFade),
EffectOptions("EffectOnly"));
var result : SfStatus = file.WaitForDoneOrCancel();
if (result != SfStatus.Success) {
fCancel = true;
} else {
file.DoEffect("Graphic Fade", "-6 dB exponential fade out",
new SfAudioSelection(wnd.File.Length - ccFade, ccFade),
EffectOptions("EffectOnly"));
result = file.WaitForDoneOrCancel();
if (result != SfStatus.Success) fCancel = true;
}

file.EndUndo(idUndo, fCancel);
DPF("Done - {0}", fCancel ? "failed and rewound changes" : "success");
}

public function FromSoundForge(app : IScriptableApp) {
ForgeApp = app;
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
Begin(app);
app.SetStatusText(String.Format("Script '{0}' is done.", Script.Name));
}

public var ForgeApp : IScriptableApp = null;
public function DPF(sz) { ForgeApp.OutputText(sz);}
public function DPF(sz,o) { ForgeApp.OutputText(System.String.Format(sz,o)); }
public function DPF(sz,o,o2) { ForgeApp.OutputText(System.String.Format(sz,o,o2)); }

public function DPF(sz,o,o2,o3) { ForgeApp.OutputText(System.String.Format(sz,o,o2,o3)); }

} // class EntryPoint