{"id":5281,"date":"2024-08-05T10:56:23","date_gmt":"2024-08-05T01:56:23","guid":{"rendered":"https:\/\/blog.criware.com\/?p=5281"},"modified":"2024-08-05T10:56:23","modified_gmt":"2024-08-05T01:56:23","slug":"automated-loop-marker-setup-with-robot-api","status":"publish","type":"post","link":"https:\/\/blog.criware.com\/index.php\/2024\/08\/05\/automated-loop-marker-setup-with-robot-api\/","title":{"rendered":"Automated Loop Marker Setup with Robot API"},"content":{"rendered":"<p>There are several ways to loop audio content in Atom Craft. At the Material level, you can either keep the looping information from the original wave file or set the Material\u2019s properties to loop. This is useful when the Material is always expected to be played as a loop or if it is the only Material referenced by a Cue.<\/p>\n<p>For multi-track Cues that may trigger other events while a Material is looped, it is recommended to insert a Sequence Loop Marker in the Cue instead. This makes it easier to create repeating patterns within a Cue.<\/p>\n<p>If your loop is tied to the duration of a Waveform Region, the start and end points of the Loop Marker must be set manually, which can be cumbersome and error-prone on larger projects. However, the Robot API can be used to automatically set up the marker around the selected Waveform Region.<br \/>\n&nbsp;<\/p>\n<div style=\"max-width: 700px; margin: 0 auto; margin-bottom: 20px; border: 1px solid #aaa;\">\n<div style=\"width: 800px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-5281-1\" width=\"800\" height=\"423\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/video_robotapi_loopmarker.mp4?_=1\" \/><a href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/video_robotapi_loopmarker.mp4\">https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/video_robotapi_loopmarker.mp4<\/a><\/video><\/div>\n<\/div>\n<h1 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">\nUser Variable<br \/>\n<\/h1>\n<p>\nAnother advantage of using Sequence Loop Markers is that the number of loops can be set in case the Cue should not repeat itself indefinitely. We can prompt the user to enter the number and assign it to a Robot API&#8217;s user variable, which can then be accessed directly from the Atom Craft&#8217;s script editor.\n<\/p>\n<p>\nFrom the code side, after importing all the required modules, the user variable can be set as follows:\n<\/p>\n<pre><code>import sys\r\nimport os\r\nimport cri.atomcraft.debug as acdebug\r\nimport cri.atomcraft.project as acproject\r\n\r\n# --BeginUserVariable\r\n\"\"\"\r\nLOOP_COUNT:\r\n\ttype:number\r\n\tcomment:Number of Loops (0 for infinite)\r\n\"\"\"\r\nLOOP_COUNT = 0\r\n# --EndUserVariable\r\n<\/code><\/pre>\n<p>For more information about User Variables check <a href=\"https:\/\/blog.criware.com\/index.php\/2023\/07\/12\/batch-renaming-with-robot-api\/\">our previous tutorial<\/a> where we explain how to use them in detail.<\/p>\n<p>The LOOP_COUNT user variable should now appear inside the right panel of the script editor. The <em>Loop Count<\/em> property of the Sequence Loop Marker accepts a number starting from 1; if the user enters 0, we will set the property to infinite.<\/p>\n<p style=\"text-align:center;\">\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/01-User-Variable.png\" alt=\"01 User Variable\" width=\"753\" height=\"383\" class=\"alignnone size-full wp-image-5286\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/01-User-Variable.png 753w, https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/01-User-Variable-300x153.png 300w\" sizes=\"auto, (max-width: 753px) 100vw, 753px\" \/><\/p>\n<p><h1 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Scripting<\/h1>\n<p>Since we want to create the Loop Marker based on a Waveform Region, we need to retrieve information about the selected Waveform, determine the Material it references, and find out the Cue it is associated with.<\/p>\n<ul>\n<li>We use <em>get_selected_objects<\/em> to retrieve the ID of the selected Waveform Region.<\/li>\n<li>Then, the <em>get_parent<\/em> function is called to get the Cue to which the Waveform Region belongs.<\/li>\n<li>To get the Material, we simply use the <em>get_value<\/em> function on the <em>LinkMaterial<\/em> property of the Waveform Region.<\/li>\n<\/ul>\n<pre><code># Get selected Waveform Regions\r\nselected_waveforms = acproject.get_selected_objects(\"WaveformRegion\")[\"data\"]\r\n<strong>if<\/strong> <strong>not<\/strong> selected_waveforms:\r\n\tacdebug.warning(\"Please select a Waveform Region\")\r\n\tsys.exit()\r\n\r\n# Get the Cue in which the Waveform Region is located\r\ncue = acproject.get_parent(selected_waveforms[0], \"Cue\")[\"data\"]\r\n\r\n# Get the Material referenced by the Waveform Region\r\nmaterial = acproject.get_value(selected_waveforms[0], \"LinkMaterial\")[\"data\"]\r\n<\/code><\/pre>\n<p>To retrieve the start and end times of the selected Waveform Region:<\/p>\n<ul>\n<li>We call <em>get_value<\/em> on the <em>DelayTimeMS<\/em> property to know where the Waveform is starting in the Cue.<\/li>\n<li>For the end time, we need to look at the Material associated with the Waveform. Based on the sample rate and the number of samples used by the Material, we can easily calculate the duration in milliseconds. This value is then added to the start time of the waveform to get the precise time at which it ends in the Cue.<\/li>\n<\/ul>\n<pre><code># Get the start time of the Waveform Region in the Sequence\r\nwaveform_start = acproject.get_value(selected_waveforms[0], \"DelayTimeMS\")[\"data\"]\r\n\r\n# Get the length of the Waveform Region by calculating the duration of the Material\r\nmaterial_sample_rate = acproject.get_value(material, \"SamplingRate\")[\"data\"]\r\nmaterial_samples = acproject.get_value(material, \"SampleFrames\")[\"data\"]\r\nmaterial_duration = (1000 * float(material_samples)) \/ float(material_sample_rate)\r\n\r\n# Calculate the end time in ms of the Waveform Region in the Sequence\r\nwaveform_end = (float(waveform_start) + material_duration)\r\n<\/code><\/pre>\n<p>We now have all the required information to create the Sequence Loop Marker:<\/p>\n<ul>\n<li>Create the Loop Marker at the Cue level by using the <em>create_object<\/em> function.<\/li>\n<li>Test if the <em>InfinityLoopFlag<\/em> property must be set to <em>True<\/em> (when the LOOP_COUNT User Variable is lesser than 1). Otherwise, use the number stored in LOOP_COUNT to set the value of the <em>LoopCount<\/em> property.<\/li>\n<li>Finally use the waveform_end and waveform_start variables to set the MarkerEndTime and MarkerStartTime properties, respectively.<\/li>\n<\/ul>\n<pre><code># Create the Sequence Loop Marker\r\nmarker = acproject.create_object(cue, \"LoopMarker\", \"My Loop\")[\"data\"]\r\n\r\n# Set the number of loops, loop start, and loop end\r\n<strong>if<\/strong> LOOP_COUNT &lt; 1:\r\n\tacproject.set_value(marker, \"InfinityLoopFlag\", \"True\")\r\n<strong>else<\/strong>:\r\n\tacproject.set_value(marker, \"LoopCount\", LOOP_COUNT)\r\nacproject.set_value(marker, \"MarkerEndTime\", waveform_end)\r\nacproject.set_value(marker, \"MarkerStartTime\", waveform_start)\r\n<\/code><\/pre>\n<p>This is all we need! You can download the full script below and test it. Simply select a Waveform Region in a Cue, and run the script. A Sequence Loop Marker matching the length of the Waveform will be automatically created.<\/p>\n<div style=\"max-width: 800px; margin: 0 auto; margin-bottom: 20px; text-align: center;\">\n<a style=\"display: block; border: 1px solid #ccc; padding: 20px; max-width: 100%; margin: 0 auto;\" href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2024\/03\/Script_RobotAPI_CreateLoopMarker.zip\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1813\" style=\"display: block; margin: 0 auto;\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2018\/06\/zip.png\" alt=\"zip\" width=\"80\" height=\"78\">Script_RobotAPI_CreateLoopMarker<\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>There are several ways to loop audio content in Atom Craft. At the Material level, you can either keep the<\/p>\n","protected":false},"author":2,"featured_media":5306,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[5,7],"tags":[],"class_list":["post-5281","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-adx","category-tutorials"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/5281","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/comments?post=5281"}],"version-history":[{"count":18,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/5281\/revisions"}],"predecessor-version":[{"id":5568,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/5281\/revisions\/5568"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media\/5306"}],"wp:attachment":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media?parent=5281"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/categories?post=5281"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/tags?post=5281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}