/ HALion Developer Resource / HALion Script / Class Reference /

Audio File

The AudioFile class describes the properties of audio files.


On this page:

AudioFile Class, analyzePitch, cancelDecompose, cancelPitchAnalysis, decompose, getDecomposeProgress, getOnsets, getPeak, getPitch, getPitchAnalysisProgress


Classes

AudioFile Class

Description

The AudioFile.open function creates an AudioFile object of the specified audio file. The AudioFile object can be used to retrieve information from the audio file, for example, the sample rate, bit depth, length in samples, etc. The AudioFile object has the following fields.

❕ All fields of the AudioFile object are read-only.

Available in: Controller, Processor.

Fields

FieldDescriptionValue Type
.validIndicates if the file is a supported audio file and whether it could be opened or not.boolean
.fileNameThe file name that was used for opening the audio file.string
.rateThe sample rate of the audio file. Returns nil if the audio file could not be opened or is invalid.number
.bitsThe bit depth of the audio file. Returns nil if the audio file could not be opened or is invalid.number
.channelsThe number of channels of the audio file. Returns nil if the audio file could not be opened or is invalid.number
.lengthThe number of samples in the audio file. Returns nil if the audio file could not be opened or is invalid.number
.rootKeyThe root key stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.keyLowThe lowest key of the key range stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.keyHighThe highest key of the key range stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.velLowThe lowest velocity of the velocity range stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.velHighThe highest velocity of the velocity range stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.detuneThe tune offset in cents stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.levelThe level offset in dB stored in the sampler chunk of the audio file. Returns nil if the audio file does not contain an appropriate sampler chunk or could not be opened or is invalid.number
.tempoThe tempo in bpm stored in a data chunk of the audio file. Returns nil if the audio file does not contain an appropriate data chunk or could not be opened or is invalid.number
.beatsThe number of beats stored in a data chunk of the audio file. Returns nil if the audio file does not contain an appropriate data chunk or could not be opened or is invalid.number
.signatureA pair of values for the numerator and denominator of the signature stored in a data chunk of the audio file. The values are nil if the audio file does not contain an appropriate data chunk or could not be opened or is invalid.number, number
.sampleStartThe position of the sample start in samples stored in a data chunk of the audio file. Returns nil if the audio file does not contain an appropriate data chunk or could not be opened or is invalid.number
.sampleEndThe position of the sample end in samples stored in a data chunk of the audio file. Returns nil if the audio file does not contain an appropriate data chunk or could not be opened or is invalid.number
.loopsThe loop start and end positions in samples stored in a data chunk of the audio file. The returned table is an array that contains tables with the fields loopStart and loopEnd for each loop. Returns nil if the audio file does not contain an appropriate data chunk or could not be opened or is invalid.table

Example

-- Open an audio file from HALion Sonic 1.0.

fname = "vstsound://502B301A6C914CEDA5C7500DC890C4DC/.Samples/g:/projects/yamahacontentserver/download/release/smtg/winds/Samples/DP060_FluteC3.wav"
af = AudioFile.open(fname)
loops = af.loops

-- Print information from the audio file.

if af.valid then
  print(fname, "opened.")
  print("Sample Rate: ", af.rate)
  print("Bit Depth: ", af.bits)
  print("Channels: ", af.channels)
  print("Sample Length: ", af.length)
  if loops then
    print("Loop Start: ", loops[1].loopStart)
    print("Loop End: ", loops[1].loopEnd)
  end
else
  print(fname, "does not exist.")
end

Jump to Top

Methods

analyzePitch

analyzePitch(callback, channel)

(Since HALion 6.3)

Description

Function to analyze the pitch of an audio file. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. The arguments callback and channel are optional. If called without a callback function, analyzePitch will be executed in the same thread. If called with a callback function as argument, analyzePitch will be executed in a separate, parallel thread. You can specify the channel to be analyzed with the channel argument. Without the channel argument multiple channels of an audio file will be summed before the pitch is analyzed. The callback function is called with the AudioFile object as the first and the channel as the second argument after the pitch has been analyzed. The results of analyzePitch are cashed as long as the corresponding AudioFile object exists. The function itself does not return any pitch information. You must use getPitch to obtain the analyzed pitch.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
callbackCallback function that is called with the AudioFile object as argument after the pitch has been analyzed.function, optional
channelUse this to specify the channel of the audio file to be analyzed. Leave this empty or set this to 0 for summing all audio channels before they are analyzed.number, optional

Example

channelNames = { [0] = "All", "Left", "Right" }
  
defineParameter( "Channel", nil, 0, channelNames)
defineParameter( "Start", nil, false, function() if Start then onStart() end end)
defineParameter( "Cancel", nil, false)
  
-- Requires the Skylab content.
path = "vstsound://724ACB205EFF46F885735D1B216C37AD/.AppData/Steinberg/Skylab/Sub Presets/Layer Presets/Ambient Pads/Ambient Pad 01.vstpreset"
layer = loadPreset(path)
  
function onPitchAnalysisFinished(audioFile, channelNum)
    print("Progress: 100%")
    print(channelNames[channelNum].." channel(s) of "..audioFile.fileName.." analyzed.")
end
  
function onStart()
    zones = layer:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        print("File: "..samplePath)
        local afile = AudioFile.open(samplePath)
        afile:analyzePitch(onPitchAnalysisFinished, Channel)
        while afile:getPitchAnalysisProgress(Channel) < 1 do
            if Cancel then
                afile:cancelPitchAnalysis(Channel)
                break
            end
            local progressPercent = 100 * afile:getPitchAnalysisProgress(Channel)
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Canceled!")
            break
        end
        local pitch = afile:getPitch(0, -1, Channel)
        print("Analyzed Pitch: "..pitch)
    end
    print("Done!")
    Start = false
end

Jump to Top

cancelDecompose

cancelDecompose()

(Since HALion 7.0)

Description

Function to cancel the decompose function for an audio file. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. To cancel the decompose of a certain audio file, the AudioFile object of the cancelDecompose function must match the AudioFile object of the corresponding decompose function.

Available in: Controller.

Example

outputModes = { "Tonal", "Noise", "All", "Mix", }
 
defineParameter { name = "Decompose", default = false, onChanged = function() if Decompose then onDecompose() end end }
defineParameter { name = "Cancel", default = false}
defineParameter { name = "Sensitivity", default = -24, min = -96, max = 0, increment = 0.1 }
defineParameter { name = "Cutoff", default = 20000, min = 20, max = 20000, increment = 1 }
defineParameter { name = "Duration", default = 80, min = 0, max = 100, increment = 0.1 }
defineParameter { name = "TonalLevel", default = 0, min = -96, max = 12, increment = 0.1 }
defineParameter { name = "NoiseLevel", default = 0, min = -96, max = 12, increment = 0.1 }
defineParameter { name = "Start", default = 0, min = 0, max = 1000, increment = 1 }
defineParameter { name = "Length", default = 0, min = 0, max = 1000, increment = 1 }
defineParameter { name = "OutputMode", default = DecomposeOutputMode.all, strings = outputModes }
defineParameter { name = "OutputPath", default = "" }
defineParameter { name = "Subfolder", default = "" }
 
function onDecomposeFinished(audioFile, file1, file2)
    print("Progress: 100%")
    print(audioFile.fileName, audioFile.length)
    if file1 then
        local afile1 = AudioFile.open(file1)
        print(afile1.fileName, afile1.length)
    end
    if file2 then
        local afile2 = AudioFile.open(file2)
        print(afile2.fileName, afile2.length)
    end
end
 
function onDecompose()
    zones = this.parent:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        local afile = AudioFile.open(samplePath)
        local startSamples = Start * afile.rate/1000
        local lengthSamples = Length * afile.rate/1000
        if not Subfolder == "" then
            if OutputPath == "" then
                OutputPath = getDecomposeOutputPath(samplePath)..Subfolder
            else
                OutputPath = OutputPath..Subfolder
            end
        end
        print("Decompose: "..samplePath)
        afile:decompose{
            callback = onDecomposeFinished,
            start = startSamples,
            length = lengthSamples,
            sensitivity = Sensitivity,
            cutoff = Cutoff,
            duration = Duration,
            tonalLevel = TonalLevel,
            noiseLevel = NoiseLevel,
            outputMode = OutputMode,
            outputPath = OutputPath,
        }
        while afile:getDecomposeProgress() < 1 do
            if Cancel then
                afile:cancelDecompose()
                break
            end
            local progress, errorMessage = afile:getDecomposeProgress()
            if errorMessage then
                print(errorMessage)
                break
            end
            local progressPercent = 100 * progress
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Decompose Canceled!")
            break
        end
    end
    print("Decompose finished.")
    Decompose = false
end

Jump to Top

cancelPitchAnalysis

cancelPitchAnalysis(channel)

(Since HALion 6.3)

Description

Function to cancel a pitch analysis you started with analyzePitch. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. The channel argument specifies the channel of the audio file. The AudioFile object and the channel argument must match the call to analyzePitch.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
channelUse this to specify the channel of the audio file that is being analyzed.number, optional

Example

channelNames = { [0] = "All", "Left", "Right" }
  
defineParameter( "Channel", nil, 0, channelNames)
defineParameter( "Start", nil, false, function() if Start then onStart() end end)
defineParameter( "Cancel", nil, false)
  
-- Requires the Skylab content.
path = "vstsound://724ACB205EFF46F885735D1B216C37AD/.AppData/Steinberg/Skylab/Sub Presets/Layer Presets/Ambient Pads/Ambient Pad 01.vstpreset"
layer = loadPreset(path)
  
function onPitchAnalysisFinished(audioFile, channelNum)
    print("Progress: 100%")
    print(channelNames[channelNum].." channel(s) of "..audioFile.fileName.." analyzed.")
end
  
function onStart()
    zones = layer:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        print("File: "..samplePath)
        local afile = AudioFile.open(samplePath)
        afile:analyzePitch(onPitchAnalysisFinished, Channel)
        while afile:getPitchAnalysisProgress(Channel) < 1 do
            if Cancel then
                afile:cancelPitchAnalysis(Channel)
                break
            end
            local progressPercent = 100 * afile:getPitchAnalysisProgress(Channel)
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Canceled!")
            break
        end
        local pitch = afile:getPitch(0, -1, Channel)
        print("Analyzed Pitch: "..pitch)
    end
    print("Done!")
    Start = false
end

Jump to Top

decompose

decompose{arguments}

(Since HALion 7.0)

Description

Function to decompose an audio file into its tonal and noise components. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. The decompose function can be configured with named arguments. The named arguments are optional and if called without, decompose will be executed with its default settings.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
callbackThis callback function is called with the AudioFile object and the file path of the ouput sample(s) as arguments after the original sample has been decomposed. If called without a callback function, decompose will be executed in the same thread. If called with a callback function as argument, decompose will be executed in a separate, parallel thread.function, optional
startThe start position in samples. The created samples are trimmed to this position. The default is 0 samples.number, optional
lengthThe duration in samples. Set this to less than or equal to 0 to use all samples from the specified start to the end of the sample. By default, everything from start to the end of the sample is decomposed. The created samples are trimmed to this length.number, optional
sensitivityDetermines the minimum level difference that is needed to distinguish the tonal from the noise signals. The sensitivity is specified in dB and the value range is from -96 to 0 dB. The default is -24 dB.number, optional
cutoffSets the frequency limit below which the algorithm detects tonal signals. Any signals above the cutoff frequency are classified as noise, regardless of the sensitivity and duration arguments. The cutoff is specified in Hz and the value range is from 20 to 20000 Hz. The default is 20000 Hz.number, optional
durationAllows you to specify the minimum length for a tonal signal in milliseconds. Signals that are shorter than the specified duration are classified as noise, longer signals are classified as tonal. The value range is fom 0 to 100 ms. The default is 80 ms.number, optional
tonalLevelSpecifies the level of the tonal component in dB. The value range is from -96 to +12 dB. The default is 0 dB.number, optional
noiseLevelSpecifies the level of the noise component in dB. The value range is from -96 to +12 dB. The default is 0 dB.number, optional
outputModeDefines if only one of the components, both components, or a mix of them is created. See Decompose Output Modes for details.number, optional
outputPathSpecifies the path for the decomposed audio files. If the string is empty, invalid, or nil, the file paths of the decompose settings of the plug-in will be used. The default is nil.string, optional

❕ Samples that were loaded from a VST Sound container can only be decomposed if the ouputPath argument is set to a valid file location. You can use getDecomposeOutputPath to obtain the file location from the decompose settings of the plug-in.

Example

outputModes = { "Tonal", "Noise", "All", "Mix", }
 
defineParameter { name = "Decompose", default = false, onChanged = function() if Decompose then onDecompose() end end }
defineParameter { name = "Cancel", default = false}
defineParameter { name = "Sensitivity", default = -24, min = -96, max = 0, increment = 0.1 }
defineParameter { name = "Cutoff", default = 20000, min = 20, max = 20000, increment = 1 }
defineParameter { name = "Duration", default = 80, min = 0, max = 100, increment = 0.1 }
defineParameter { name = "TonalLevel", default = 0, min = -96, max = 12, increment = 0.1 }
defineParameter { name = "NoiseLevel", default = 0, min = -96, max = 12, increment = 0.1 }
defineParameter { name = "Start", default = 0, min = 0, max = 1000, increment = 1 }
defineParameter { name = "Length", default = 0, min = 0, max = 1000, increment = 1 }
defineParameter { name = "OutputMode", default = DecomposeOutputMode.all, strings = outputModes }
defineParameter { name = "OutputPath", default = "" }
defineParameter { name = "Subfolder", default = "" }
 
function onDecomposeFinished(audioFile, file1, file2)
    print("Progress: 100%")
    print(audioFile.fileName, audioFile.length)
    if file1 then
        local afile1 = AudioFile.open(file1)
        print(afile1.fileName, afile1.length)
    end
    if file2 then
        local afile2 = AudioFile.open(file2)
        print(afile2.fileName, afile2.length)
    end
end
 
function onDecompose()
    zones = this.parent:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        local afile = AudioFile.open(samplePath)
        local startSamples = Start * afile.rate/1000
        local lengthSamples = Length * afile.rate/1000
        if not Subfolder == "" then
            if OutputPath == "" then
                OutputPath = getDecomposeOutputPath(samplePath)..Subfolder
            else
                OutputPath = OutputPath..Subfolder
            end
        end
        print("Decompose: "..samplePath)
        afile:decompose{
            callback = onDecomposeFinished,
            start = startSamples,
            length = lengthSamples,
            sensitivity = Sensitivity,
            cutoff = Cutoff,
            duration = Duration,
            tonalLevel = TonalLevel,
            noiseLevel = NoiseLevel,
            outputMode = OutputMode,
            outputPath = OutputPath,
        }
        while afile:getDecomposeProgress() < 1 do
            if Cancel then
                afile:cancelDecompose()
                break
            end
            local progress, errorMessage = afile:getDecomposeProgress()
            if errorMessage then
                print(errorMessage)
                break
            end
            local progressPercent = 100 * progress
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Decompose Canceled!")
            break
        end
    end
    print("Decompose finished.")
    Decompose = false
end

Jump to Top

getDecomposeProgress

getDecomposeProgress()

(Since HALion 7.0)

Description

Function to monitor the progress of the decompose function for an audio file. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. To get the progress of a certain audio file that is being decomposed, the AudioFile object of the getDecomposeProgress function must match the AudioFile object of the corresponding decompose function. The function returns two values: the progress as a value between 0 and 1 and an error message if the decompose did not succeed.

Available in: Controller.

Return Values

Returns the progress as a float value between 0 and 1, and an error message if the decompose did not succeed. The error message returns nil if the decompose was successful.

Example

outputModes = { "Tonal", "Noise", "All", "Mix", }
 
defineParameter { name = "Decompose", default = false, onChanged = function() if Decompose then onDecompose() end end }
defineParameter { name = "Cancel", default = false}
defineParameter { name = "Sensitivity", default = -24, min = -96, max = 0, increment = 0.1 }
defineParameter { name = "Cutoff", default = 20000, min = 20, max = 20000, increment = 1 }
defineParameter { name = "Duration", default = 80, min = 0, max = 100, increment = 0.1 }
defineParameter { name = "TonalLevel", default = 0, min = -96, max = 12, increment = 0.1 }
defineParameter { name = "NoiseLevel", default = 0, min = -96, max = 12, increment = 0.1 }
defineParameter { name = "Start", default = 0, min = 0, max = 1000, increment = 1 }
defineParameter { name = "Length", default = 0, min = 0, max = 1000, increment = 1 }
defineParameter { name = "OutputMode", default = DecomposeOutputMode.all, strings = outputModes }
defineParameter { name = "OutputPath", default = "" }
defineParameter { name = "Subfolder", default = "" }
 
function onDecomposeFinished(audioFile, file1, file2)
    print("Progress: 100%")
    print(audioFile.fileName, audioFile.length)
    if file1 then
        local afile1 = AudioFile.open(file1)
        print(afile1.fileName, afile1.length)
    end
    if file2 then
        local afile2 = AudioFile.open(file2)
        print(afile2.fileName, afile2.length)
    end
end
 
function onDecompose()
    zones = this.parent:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        local afile = AudioFile.open(samplePath)
        local startSamples = Start * afile.rate/1000
        local lengthSamples = Length * afile.rate/1000
        if not Subfolder == "" then
            if OutputPath == "" then
                OutputPath = getDecomposeOutputPath(samplePath)..Subfolder
            else
                OutputPath = OutputPath..Subfolder
            end
        end
        print("Decompose: "..samplePath)
        afile:decompose{
            callback = onDecomposeFinished,
            start = startSamples,
            length = lengthSamples,
            sensitivity = Sensitivity,
            cutoff = Cutoff,
            duration = Duration,
            tonalLevel = TonalLevel,
            noiseLevel = NoiseLevel,
            outputMode = OutputMode,
            outputPath = OutputPath,
        }
        while afile:getDecomposeProgress() < 1 do
            if Cancel then
                afile:cancelDecompose()
                break
            end
            local progress, errorMessage = afile:getDecomposeProgress()
            if errorMessage then
                print(errorMessage)
                break
            end
            local progressPercent = 100 * progress
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Decompose Canceled!")
            break
        end
    end
    print("Decompose finished.")
    Decompose = false
end

Jump to Top

getOnsets

getOnsets(start, length, peakThreshold, sensThreshold, minLength)

(Since HALion 6.4.0)

Description

Function to analyze the onsets in an audio file. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. The onset analysis is performed on the sum of all channels in the audio file. The arguments start and length define the time range in the audio file to be analyzed. The peakThreshold and sensThreshold arguments determine the minimum level and the weight of an onset, the minLength argument determines the minimum duration between consecutive onsets.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
startThe start position in samples.number
lengthThe duration in samples. Set this to equal to or less than 0 to use all samples from the specified start to the end of the sample.number
peakThresholdThe minimum level in decibels. Onsets with lower level are skipped. The value range is from -96 to 0.number
sensThresholdThe minimum weight in percent. Onsets with lower weight are skipped. The value range is from 0 to 100.number
minLengthThe minimum duration between consecutive onsets in milliseconds. The value range is from 0 to 10000.number

Return Values

Returns an array with the positions of the detected onsets.

Example

fname = "vstsound://271CB2CFA75E4295B1C273FA651FE11D/.Samples/g:/projects/yamahacontentserver/Download/Release/ycj/ME_Waveform/Loop145/samples/Loop145_072(2).wav"
 
af = AudioFile.open(fname)
 
onsets = af:getOnsets(0, -1, -24, 0, 10)
  
for i, pos in ipairs(onsets) do
   print(i.." ".."Onset: "..pos)
end

Jump to Top

getPeak

getPeak(start, length, rms)

Description

Function to analyze the levels in an audio file. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. The arguments start and length define the range in the audio file to be analyzed. The rms argument determines whether the peak level or the RMS level of the specified range is returned.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
startThe start position in samples.number
lengthThe duration in samples. Set this to equal to or less than 0 to use all samples from the specified start to the end of the file.number
rmsIf this is set to 0, the peak level of the specified range will be returned. If this is set to a value above 0, the RMS level over the specified range will be calculated.number

Return Values

Returns the level of the specifed range as a linear value. The example shows how to convert the value from linear to dB.

Example

function lin2db(lin)
  return 20 * math.log(lin) / math.log(10)
end

fname = "vstsound://F29C895D6D8E4D6C9BCBBA5198412192/.samples/Ambient Pad 01/Ambient Pad 01 - C3.tg3c"
af = AudioFile.open(fname)

-- Analyze the peak level in the first 1000 samples.

attpeak = af:getPeak(0, 1000, 0)

-- Analyze the RMS level in the range from 1000 samples till the end of the file.

susrms = af:getPeak(1000, -1, 1)
print("Attack Peak:", attpeak, "(", lin2db(attpeak), "dB )")
print("Sustain RMS:", susrms, "(", lin2db(susrms), "dB )")

Jump to Top

getPitch

getPitch(start, length, channel)

(Since HALion 6.3)

Description

Function to obtain the pitch of an audio file that has been analyzed with analyzePitch. The audio file you want to obtain the pitch from is specified with the AudioFile object that is returned by the AudioFile.open function. The arguments start and length define the range in the audio file that is used for obtaining the pitch. The channel argument specifies the channel of the audio file that was analyzed. The AudioFile object and the channel argument must match the call to analyzePitch. The function returns two values: The pitch as MIDI note number with decimals for cents and a boolean for voiced/unvoiced detection. If length is greater than 20 ms, the average of the pitches in the specified range is returned. If the audio file has not been analyzed in advance, getPitch returns nil.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
startThe start position in samples.number
lengthThe duration in samples. Set this to less than or equal to 0 to use all samples from the specified start to the end of the file.number
channelUse this to specify the audio channel that was analyzed.number, optional

Return Values

Returns a tuple with two values:

  • A float value representing the pitch as MIDI note number with decimals for cents,
  • a boolean for voiced/unvoiced detection. The return value true means that a pitch was detected in the specified range.

If length is greater than 20 ms, the average of the pitches in the specified range is returned. If the audio file has not been analyzed in advance, getPitch returns nil.

Example

channelNames = { [0] = "All", "Left", "Right" }
  
defineParameter( "Channel", nil, 0, channelNames)
defineParameter( "Start", nil, false, function() if Start then onStart() end end)
defineParameter( "Cancel", nil, false)
  
-- Requires the Skylab content.
path = "vstsound://724ACB205EFF46F885735D1B216C37AD/.AppData/Steinberg/Skylab/Sub Presets/Layer Presets/Ambient Pads/Ambient Pad 01.vstpreset"
layer = loadPreset(path)
  
function onPitchAnalysisFinished(audioFile, channelNum)
    print("Progress: 100%")
    print(channelNames[channelNum].." channel(s) of "..audioFile.fileName.." analyzed.")
end
  
function onStart()
    zones = layer:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        print("File: "..samplePath)
        local afile = AudioFile.open(samplePath)
        afile:analyzePitch(onPitchAnalysisFinished, Channel)
        while afile:getPitchAnalysisProgress(Channel) < 1 do
            if Cancel then
                afile:cancelPitchAnalysis(Channel)
                break
            end
            local progressPercent = 100 * afile:getPitchAnalysisProgress(Channel)
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Canceled!")
            break
        end
        local pitch = afile:getPitch(0, -1, Channel)
        print("Analyzed Pitch: "..pitch)
    end
    print("Done!")
    Start = false
end

Jump to Top

getPitchAnalysisProgress

getPitchAnalysisProgress(channel)

(Since HALion 6.3)

Description

Function to monitor the progress of analyzePitch. You specify the audio file with the AudioFile object that is returned by the AudioFile.open function. The channel argument specifies the channel of the audio file. The AudioFile object and the channel argument must match the call to analyzePitch. The function returns the progress as a float value between 0 and 1.

Available in: Controller.

Arguments

ArgumentDescriptionValue Type
channelUse this to specify the channel of the audio file that is being analyzed.number, optional

Return Values

Returns the progress as a float value between 0 and 1.

Example

channelNames = { [0] = "All", "Left", "Right" }
  
defineParameter( "Channel", nil, 0, channelNames)
defineParameter( "Start", nil, false, function() if Start then onStart() end end)
defineParameter( "Cancel", nil, false)
  
-- Requires the Skylab content.
path = "vstsound://724ACB205EFF46F885735D1B216C37AD/.AppData/Steinberg/Skylab/Sub Presets/Layer Presets/Ambient Pads/Ambient Pad 01.vstpreset"
layer = loadPreset(path)
  
function onPitchAnalysisFinished(audioFile, channelNum)
    print("Progress: 100%")
    print(channelNames[channelNum].." channel(s) of "..audioFile.fileName.." analyzed.")
end
  
function onStart()
    zones = layer:findZones(true)
    for i, zone in ipairs(zones) do
        local samplePath = zone:getParameter("SampleOsc.Filename")
        print("File: "..samplePath)
        local afile = AudioFile.open(samplePath)
        afile:analyzePitch(onPitchAnalysisFinished, Channel)
        while afile:getPitchAnalysisProgress(Channel) < 1 do
            if Cancel then
                afile:cancelPitchAnalysis(Channel)
                break
            end
            local progressPercent = 100 * afile:getPitchAnalysisProgress(Channel)
            print(string.format("Progress: %2d%%", progressPercent))
            wait(2000)
        end
        if Cancel then
            Cancel = false
            print("Canceled!")
            break
        end
        local pitch = afile:getPitch(0, -1, Channel)
        print("Analyzed Pitch: "..pitch)
    end
    print("Done!")
    Start = false
end

Jump to Top