Python Example

iris-sdk-sample.py

 1import iris.sdk
 2import numpy as np
 3import soundfile as sf
 4from pathlib import Path
 5
 6from utils import check_licence_info, check_context_config, check_context_request, create_output_filepath #, file_to_string
 7
 8
 9def process_callback(event):
10    match event.type:
11        case iris.sdk.ProcessEventType.start:
12            print(f"\rProcessing: started")
13        case iris.sdk.ProcessEventType.process:
14            print(f"Processing: {event.percentage:.2f}%", end='\r')
15        case iris.sdk.ProcessEventType.end:
16            print(f"\nProcessing: ended")
17
18
19if __name__ == "__main__":
20    # initialise iris sdk. either pass in the licence and key as strings or let the sdk discover
21    # them from its default data location. See readme.md for default locations
22    # licence = file_to_string("/full/path/to/iris.lic")
23    # key = file_to_string("/full/path/to/iris.key")
24    # info = iris.sdk.init(licence, key)
25    info = iris.sdk.init()
26    print(f"Initialised iris-sdk {info.version} for {info.name}")
27    check_licence_info(info)
28
29    # Load a wav file and fetch the sample rate and data format
30    script_dir = Path(__file__).resolve().parent
31    input_filepath = script_dir.parent / "sample_audio" / "breaking_point_f32_48k.wav"
32    audio_in, sample_rate = sf.read(input_filepath, dtype='float32')
33    file_info = sf.info(input_filepath)
34    original_format = file_info.subtype
35
36    # prepare an output buffer to hold the processed audio
37    audio_out = np.zeros_like(audio_in, dtype=np.float32)
38
39    # Create an audio processing context request
40    context_request = iris.sdk.AudioContextRequest()
41    context_request.processors = ["passthrough"]  # set the processor chain to use
42    context_request.sample_rate = sample_rate  # set the sample rate of the input audio
43    context_request.channel_count = file_info.channels  # set the channel count of the input audio
44    context_request.resampler_mode = iris.sdk.ResamplerMode.HQ  # set the resampler quality (HQ or SPEED)
45    check_context_request(context_request)
46
47    # Create an audio processing context using the context request
48    config = iris.sdk.create_audio_context(context_request)
49    check_context_config(config)
50
51    # Process the entire buffer in one go, accounting for any transport delay
52    # If processing a stream, call iris.sdk.process when each new buffer of stream data arrives instead
53    # In the streaming case, frames should be set to the size of the stream buffer size.
54    # If each buffer is the same size, set fixed_frame_count to true in the context request
55    # If the stream buffer size is known up front, set the buffer size in the context request
56    # streaming pseudocode
57    # while new_stream_data_available:
58    #   process_in_buffer = get_stream_source()
59    #   process_out_buffer = np.zeros_like(process_in_buffer, dtype=np.float32)
60    #   iris.sdk.process(config.context_id, process_in_buffer, process_out_buffer, len(process_in_buffer))
61    #   put_stream_sink(process_out_buffer)
62
63    print(f"Processing {input_filepath}")
64    iris.sdk.process_offline(config.context_id, audio_in, audio_out, file_info.frames, process_callback)
65
66    # save the processed output alongside the input file in the original file format
67    output_filepath = create_output_filepath(input_filepath, config.description)
68    sf.write(output_filepath, audio_out, sample_rate, subtype=original_format)
69    print(f"Saving {output_filepath}")
70
71    # Release the context
72    print(f"Cleaning up...")
73    iris.sdk.release_audio_context(config.context_id)
74    iris.sdk.cleanup()
75    print(f"Done.")

utils.py

 1import os
 2import sys
 3from pathlib import Path
 4
 5import iris.sdk
 6
 7
 8def file_to_string(file_path: str | Path) -> str:
 9    path = Path(file_path)
10    with open(path, "r") as f:
11        data = f.read()
12    return data
13
14
15def check_licence_info(info):
16    print(f"Licence Info:")
17    print(f"  {'Name:':<20}{info.name}")
18    print(f"  {'SDK Version:':<20}{info.version}")
19    print(f"  {'Expiry:':<20}{info.expiry}")
20    print(f"  {'Licence status:':<20}{info.status}")
21    print(f"")
22    print('Available processors:', *info.available_processors, sep='\n- ')
23    print(f"")
24    if not info.status == iris.sdk.LicenceStatus.LICENCE_VALID:
25        print('Invalid licence - exiting')
26        sys.exit(0)
27
28
29def check_context_request(request):
30    print(f"Audio Context Request:")
31    print(f"  {'Sample rate:':<20}{request.sample_rate}")
32    print(f"  {'Buffer length:':<20}{request.buffer_length}")
33    print(f"  {'Processors:':<20}{request.processors}")
34    print(f"  {'Resampler Mode:':<20}{request.resampler_mode}")
35    print(f"  {'Optimization:':<20}{request.optimization}")
36    print(f"  {'Fixed frame count:':<20}{request.fixed_frame_count}")
37    print(f"")
38
39
40def check_context_config(config):
41    print(f"Audio Context Configuration:")
42    print(f"  {'Context id:':<20}{config.context_id}")
43    print(f"  {'Description:':<20}{config.description}")
44    print(f"  {'Sample rate:':<20}{config.sample_rate}")
45    print(f"  {'Buffer length:':<20}{config.buffer_length}")
46    print(f"  {'Channels:':<20}{config.channel_count}")
47    if config.will_resample:
48        print(f"  {'Resampling:':<20}{config.will_resample}")
49        print(f"  {'Resampler Mode:':<20}{config.resampler_mode}")
50    print(f"  {'Optimisation:':<20}{config.optimization}")
51
52    if config.error == 0:
53        print(f"  Context Parameters:")
54        for group in config.parameters:
55            print(f"    {group.name}")
56            for param in group.parameter_descriptions:
57                print(f"      -> {param.name}")
58
59    else:
60        print(f"  {'Error:':<20}{config.error}")
61        print(f"")
62        print('Context creation failed')
63        sys.exit(0)
64
65    print(f"")
66
67
68def create_output_filepath(input_filepath, description):
69    directory, filename = os.path.split(input_filepath)
70    base_name, ext = os.path.splitext(filename)
71    return os.path.join(directory, f"{base_name}_{description.replace(' -> ', '_')}{ext}")