{"id":4788,"date":"2023-12-08T14:19:48","date_gmt":"2023-12-08T05:19:48","guid":{"rendered":"https:\/\/blog.criware.com\/?p=4788"},"modified":"2024-05-17T17:25:03","modified_gmt":"2024-05-17T08:25:03","slug":"aisac-crossfades-script-with-robot-api","status":"publish","type":"post","link":"https:\/\/blog.criware.com\/index.php\/2023\/12\/08\/aisac-crossfades-script-with-robot-api\/","title":{"rendered":"AISAC Crossfades Script with Robot API"},"content":{"rendered":"<p>Automating tedious and time-consuming tasks is one of the many benefits of using the CRI Atom Craft Robot API. For instance, there are many cases where you will need to use an AISAC to crossfade between the tracks of a Cue. This could be an engine sound where you need to blend different RPM loops, a rain sound with several levels of intensity, or a music sequence where new layers are added progressively.<\/p>\n<p>If your Cue contains more than two or three tracks, it could take a lot of time to set the AISAC graphs properly for each track. In this post, we will see how to leverage the Robot API and write a Python script that automatically creates AISAC graphs crossfading between tracks.<\/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-4788-1\" width=\"800\" height=\"423\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/Video_Script_AISAC_Xfades.mp4?_=1\" \/><a href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/Video_Script_AISAC_Xfades.mp4\">https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/Video_Script_AISAC_Xfades.mp4<\/a><\/video><\/div>\n<\/div>\n<h1 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Object User Variable<\/h1>\n<p>When creating an AISAC for an object (Cue, Track, etc.), an <strong>AISAC-Control<\/strong> must be specified. As we saw <a href=\"https:\/\/blog.criware.com\/index.php\/2023\/07\/12\/batch-renaming-with-robot-api\/\">previously<\/a>, the Robot API allows <strong>User Variables<\/strong> to be added within a script, so users can change the object\/string\/value specification in the GUI rather than directly in the code.<\/p>\n<p>A User Variable is defined as follows:<\/p>\n<pre><code>\r\n# --BeginUserVariable\r\n\"\"\"\r\nAISAC_CONTROL:\r\n  type:object\r\n  comment:AISAC-Control to use for the crossfades.\r\n\"\"\"\r\nAISAC_CONTROL = None\r\n# --EndUserVariable\r\n&nbsp;\r\n<\/code><\/pre>\n<p>We need to use a User Variable of the <em>Object<\/em> type, which is a bit different from the <em>Value<\/em> or <em>String<\/em> types. When defining an Object variable, a drag-and-drop area will appear in the script\u2019s GUI.\u00a0 Drag and drop an AISAC-Control object from the Project Tree. After clicking the Apply button, the code will be updated to get the specified object.<\/p>\n<p style=\"text-align:center;\">\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/01-Object-User-Variable.png\" alt=\"01 Object User Variable\" width=\"2162\" height=\"634\" class=\"alignnone size-full wp-image-4798\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/01-Object-User-Variable.png 2162w, https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/01-Object-User-Variable-300x88.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/01-Object-User-Variable-768x225.png 768w, https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/01-Object-User-Variable-1024x300.png 1024w\" sizes=\"auto, (max-width: 2162px) 100vw, 2162px\" \/>\n<\/p>\n<h1 style=\"font-size: 150%; font-weight: bold; margin-top: 40px;\">Script Logic<\/h1>\n<p>We can now create the AISAC and the graph for each selected track, which will have a bell shape, so sounds can smoothly fade in and out.<\/p>\n<p>We start by getting the list of selected tracks with the <em>get_selected_objects<\/em> function and determine the number of tracks.<\/p>\n<pre><code>\r\n# Get selected tracks:\r\nselected_tracks = acproject.get_selected_objects(\"Track\")[\"data\"]\r\n\r\n# Get number of tracks\r\ntrack_number = len(selected_tracks)\r\n&nbsp;\r\n<\/code><\/pre>\n<p>The center points of the bell shapes will be equidistant from each other on the X-axis. So, we first calculate the distance between two successive center points. Since the x-axis of an AISAC is between 0 and 1 we simply need to divide 1 by the number of tracks minus 1.<\/p>\n<pre><code>\r\n# Get distance between points\r\npoint_rng = 1 \/ (track_number - 1)\r\n&nbsp;\r\n<\/code><\/pre>\n<p style=\"text-align:center;\">\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/02-Point-Range.png\" alt=\"02 Point Range\" width=\"1011\" height=\"485\" class=\"alignnone size-full wp-image-4797\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/02-Point-Range.png 1011w, https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/02-Point-Range-300x144.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/02-Point-Range-768x368.png 768w\" sizes=\"auto, (max-width: 1011px) 100vw, 1011px\" \/>\n<\/p>\n<p>Now that we have the distance between each center point, we write a loop that goes through every track to create the AISAC and its graph. To achieve this, we use the <em>create_aisac<\/em> and<em> create_aisac_graph<\/em> functions. Of course, since we are creating crossfades, the AISAC graph will have to be of type <em>Volume<\/em>:<\/p>\n<pre><code>\r\nfor i in range(track_number):\r\n  # Create AISAC under the current track:\r\n  track_aisac = acproject.create_aisac(selected_tracks[i], aisac_graph_name, AISAC_CONTROL)[\"data\"]\r\n\r\n  # Create Volume graph:\r\n  volume_graph = acproject.create_aisac_graph(track_aisac, \"Volume\")[\"data\"]\r\n&nbsp;\r\n<\/code><\/pre>\n<p>Except for the first and last track, graphs should have 3 points, with the following value on the y-axis (called Destination Value for an AISAC).<\/p>\n<ul>\n<li>0 for the start point.<\/li>\n<li>1 for the center point.<\/li>\n<li>0 for the end point.<\/li>\n<\/ul>\n<p>The graphs for the first and last tracks should have a fade-out and a fade-in shape, respectively. This means they will only need two points, which are:<\/p>\n<ul>\n<li>Center and end points for the first track.<\/li>\n<li>Start and center points for the last track.<\/li>\n<\/ul>\n<p>Consequently, we will add conditions to avoid creating unwanted points for the first and last tracks.<\/p>\n<p>For the graphs to crossfade, we will also increment the position of the point on the x-axis (called Control Value for an AISAC) at each iteration.<\/p>\n<p>Graph points are created with the <em>create_aisac_point<\/em> function:<\/p>\n<pre><code>\r\n# Create graph points based on the position in the track list\r\n# Create a start point, except for the first track\r\nif i &gt; 0:\r\n  control_value_start = (point_rng * (i - 1))\r\n  destination_value_start = 0\r\n  graph_point_start = acproject.create_aisac_point(volume_graph, control_value_start, destination_value_start)[\"data\"]\r\n\r\n# Create a center point\r\ncontrol_value_center = (point_rng * i)\r\ndestination_value_center = 1\r\ngraph_point_center = acproject.create_aisac_point(volume_graph, control_value_center, destination_value_center)[\"data\"]\r\n\r\n# Create an end point, except for the last track\r\nif i &lt; track_number - 1:\r\n  control_value_end = (point_rng * (i + 1))\r\n  destination_value_end = 0\r\n  graph_point_end = acproject.create_aisac_point(volume_graph, control_value_end, destination_value_end)[\"data\"]\r\n&nbsp;\r\n<\/code><\/pre>\n<p>For the moment, with only 3 points, the graphs have triangular shapes. However, we can change the <em>CurveType<\/em> of the points to create the expected bell-shaped graphs needed for crossfading. Only the center and end points need to be updated by using the <em>set_value<\/em> function.<\/p>\n<pre><code>\r\n# Change curve type of the center point, except for the first track\r\ncurvetype_center = \"FastChange\"\r\nacproject.set_value(graph_point_center, \"CurveType\", curvetype_center)\r\n\r\n# Change curve type of the end point\r\ncurvetype_end = \"SlowChange\"\r\nacproject.set_value(graph_point_end, \"CurveType\", curvetype_end)\r\n&nbsp;\r\n<\/code><\/pre>\n<p>You can download the full script below. Open it in AtomCraft\u2019s script editor, then drag and drop an AISAC-Control on the User Variable area. Click the apply button and save the script. Finally, select the tracks and run the script to automatically create crossfades!<\/p>\n<div style=\"max-width: 800px; margin: 0 auto; margin-bottom: 20px; text-align: center;\"><a style=\"display: block; border: 1px solid #ccc; padding: 20px; max-width: 100%; margin: 0 auto;\" href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2023\/12\/AISAC-Create-Tracks-Crossfades.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\">AISAC &#8211; Create Tracks Crossfades.py<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Automating tedious and time-consuming tasks is one of the many benefits of using the CRI Atom Craft Robot API. For<\/p>\n","protected":false},"author":2,"featured_media":5386,"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-4788","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\/4788","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=4788"}],"version-history":[{"count":13,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/4788\/revisions"}],"predecessor-version":[{"id":4810,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/4788\/revisions\/4810"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media\/5386"}],"wp:attachment":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media?parent=4788"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/categories?post=4788"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/tags?post=4788"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}