Reaper-Tools

Audiokinetic Reaper Tools Repository
Log | Files | Refs

commit b94a29e1314a9246c4bfceee3d6951041a85830f
parent 984c1e8c9cca3a9a78b7e59f96f5bcb26a29d288
Author: Andrew Costa <acosta@audiokinetic.com>
Date:   Wed, 30 Nov 2022 16:41:35 -0500

Added Strata_Open associated Strata project from selected audio file.lua v1.0.0-rc.1

Change-Id: I391bc028aa087bcbf08a6c25dac0265d6f913b15

Diffstat:
ALicense.txt | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AScripts/Strata_Open associated Strata project from selected audio file.lua | 208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 280 insertions(+), 0 deletions(-)

diff --git a/License.txt b/License.txt @@ -0,0 +1,72 @@ + AUDIOKINETIC REAPER SCRIPTS LICENSE + + 1. Scripts. AUDIOKINETIC Inc. (“AUDIOKINETIC”) may make available to you from time + to time scripts or other tools related to REAPER which have the purpose of + improving the workflow of and integration with some of AUDIOKINETC’s + technologies (collectively, and with all associated documentation files, + “Scripts”). Such Scripts are made available to you under the terms of this + Scripts License (this “License”). By using the Scripts, you agree to be bound by + this License. + + 2. Title. Title, ownership rights, and intellectual property rights in the Scripts + shall remain with AUDIOKINETIC. You are granted no rights in the Scripts other + than the rights expressly set forth below. + + 3. License Grant. AUDIOKINETIC grants to any person obtaining a copy of a Script + (“you”), the unrestricted to use, copy, modify, publish, distribute, and/or + sublicense copies of the Script, subject to the terms of this License. + + 4. No Code Contribution. AUDIOKINETIC does not currently accept or and will not + consider any code contribution, unless otherwise indicated. + + 5. No Commercialization. You may not commercialize any Script or derivative work + thereof as a standalone file. + + 6. Notices. The copyright and license notices in the header file of the Script + must be included in all copies of the Script. + + 7. Disclaimer of Warranty. THE SCRIPTS ARE PROVIDED “AS IS”, WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO + EVENT SHALL AUDIOKINETIC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SCRIPTS OR THE USE OR OTHER DEALINGS IN THE SCRIPTS; IF + AUDIOKINETIC IS NEVERTHELESS LIABLE AS A MATTER OF LAW, IN NO EVENT WILL + AUDIOKINETIC'S LIABILITY ARISING OUT OF OR RELATED TO THIS LICENSE OR THE + SCRIPTS EXCEED TEN CANADIAN DOLLARS. + + 8. Termination. This license will terminate automatically if you fail to comply + with the restrictions described herein. On termination, you must destroy all + copies of the Scripts in your possession. + + 9. Export and Sanctions Controls. You agree to comply with all sanctions and + export laws, restrictions, national security controls and regulations of Canada, + the United States or any other applicable national or foreign agency or + authority. + + 10. Miscellaneous. This license represents the complete agreement concerning this + license and may be amended only in writing. If any provision of this License is + held to be unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License will be governed by and construed + under the laws of the province of Quebec and the laws of Canada applicable + therein and the parties hereto submit to the exclusive jurisdiction of the + courts of Province of Quebec, District of Montreal. + + 11. Language. You confirm that a French version of this License has been remitted + to you. It is the express wish of the parties to be bound only by the English + version of such agreement. Vous confirmez que la version française de cette + entente vous a été remise. Les parties expriment leur volonté expresse d’être + liées seulement par la version anglaise de cette entente. + +END OF TERMS AND CONDITIONS + +Copyright (c) 2022 AUDIOKINETIC Inc. + +The script in this file is licensed to use under the license available at: +https://raw.githubusercontent.com/audiokinetic/Reaper-Tools/main/License.txt (the "License"). +You may not use this file except in compliance with the License. + +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/Scripts/Strata_Open associated Strata project from selected audio file.lua b/Scripts/Strata_Open associated Strata project from selected audio file.lua @@ -0,0 +1,207 @@ +--[[ + @description Strata_Open associated Strata project from selected audio file + @author Audiokinetic + @version 1.0.0-rc.1 + @changelog + Initial release + @provides + [main=mediaexplorer] . https://raw.githubusercontent.com/audiokinetic/Reaper-Tools/$commit/Scripts/Strata_Open%20associated%20Strata%20project%20from%20selected%20audio%20file.lua + @about + The script opens up the associated Strata project for the currectly selected audio file in the Media Explorer. + @license + Copyright (c) 2022 AUDIOKINETIC Inc. + + The script in this file is licensed to use under the license available at: + https://raw.githubusercontent.com/audiokinetic/Reaper-Tools/main/License.txt (the "License"). + You may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software distributed + under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. See the License for the + specific language governing permissions and limitations under the License. +]]-- + +-- constants -- +local OK_RESULT = 1 +local OK_MESSAGE_BOX = 0 +local OK_CANCEL_MESSAGE_BOX = 1 +local MEDIA_EXPLORER_ID = 1000 +local MEDIA_EXPLORER_LIST_VIEW_ID = 1001 +local MEDIA_EXPLORER_DIRECTORY_ID = 1002 +local TRACK_VIEW_ID = 1000 +local CURRENT_PROJECT = 0 + +-- global variables -- +local SEPERATOR_CHAR = string.find(reaper.GetOS(), "Win") ~= nil and "\\" or "/" +local BROWSER_CMD = string.find(reaper.GetOS(), "OSX") ~= nil and "open" or "start" + +-- helper functions -- +local function openUrl(url) + os.execute(BROWSER_CMD .. ' "" "' .. url .. '"') +end + +local function getMetadata(pcmSource, list) + for i = 1, #list do + local _, candidate = reaper.GetMediaFileMetadata(pcmSource, list[i]) + + if candidate and candidate ~= "" then + return candidate + end + end + + return nil +end + +-- dependancy checks -- +if not reaper.JS_Window_FindChildByID or not reaper.JS_Localize or not reaper.JS_Window_Find or + not reaper.JS_ListView_ListAllSelItems or not reaper.JS_Window_GetTitle or + not reaper.JS_ListView_GetItemText or not reaper.JS_Window_SetScrollPos then + local selectedOption = reaper.ShowMessageBox("The script requires the latest version of js_ReaScriptAPI be installed.\n\nView in ReaPack?", "Open In Strata: Failed", OK_CANCEL_MESSAGE_BOX) + + if selectedOption == OK_RESULT then + if reaper.ReaPack_BrowsePackages then + reaper.ReaPack_BrowsePackages("js_ReaScriptAPI") + else + selectedOption = reaper.ShowMessageBox("Unable to locate ReaPack. You can download ReaPack by going to https://reapack.com.\n\nGo there m now?", "Open In Strata: Failed", OK_CANCEL_MESSAGE_BOX) + + if selectedOption == OK_RESULT then + openUrl("https://reapack.com") + end + end + end + + return +end + +-- get selected items in media explorer -- +local mediaExplorerWindow = reaper.OpenMediaExplorer("", false) + +if not mediaExplorerWindow then + reaper.ShowMessageBox("The script was not able to access the Media Explorer.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +local listView = reaper.JS_Window_FindChildByID(mediaExplorerWindow, MEDIA_EXPLORER_LIST_VIEW_ID) + +if not listView then + reaper.ShowMessageBox("The script was not able to access the Media Explorer File List.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +local count, indices = reaper.JS_ListView_ListAllSelItems(listView) + +if count == 0 or not indices or indices == "" then + reaper.ShowMessageBox("No file is selected in the Media Explorer File List.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +local directoryInputField = reaper.JS_Window_FindChildByID(mediaExplorerWindow, MEDIA_EXPLORER_DIRECTORY_ID) + +if not directoryInputField then + reaper.ShowMessageBox("The script was not able to access the Media Explorer Directory.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +local directory = reaper.JS_Window_GetTitle(directoryInputField) + +indices = indices .. "," + +local indexOfFirstComma = string.find(indices, ",") +local firstIndex = string.sub(indices, 0, indexOfFirstComma - 1) +local selectedFilename = reaper.JS_ListView_GetItemText(listView, tonumber(firstIndex), OK_MESSAGE_BOX) + +local filePath = directory .. SEPERATOR_CHAR .. selectedFilename + +-- Read data from wav header -- +local pcmSource = reaper.PCM_Source_CreateFromFile(filePath) +local projectName = getMetadata(pcmSource, {"IXML:PROJECT", "IXML:Project", "IXML:project"}) +local trackName = getMetadata(pcmSource, {"IXML:USER:trackName", "IXML:USER:TRACKNAME", "IXML:USER:TrackName", "IXML:USER:trackname"}) +local regionName = getMetadata(pcmSource, {"ASWG:fxName", "ASWG:FXNAME", "ASWG:FxName", "ASWG:fxname"}) + +if not projectName then + reaper.ShowMessageBox("IXML:PROJECT header missing or empty in selected file. The script expects the IXML:PROJECT header to container the associated project name.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +if not trackName then + reaper.ShowMessageBox("IXML:USER:trackName header missing in selected file. The script expects the IXML:USER:trackName header to container the associated track name.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +if not regionName then + reaper.ShowMessageBox("ASWG:fxName header missing in selected file. The script expects the ASWG:fxName header to container the associated region name.", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +local projectPath = nil +local directoryToSearchReverse = string.reverse(directory) +local nextProjectDirectory = directory +local nextSeperatorChar = 0 + +while true do + nextProjectPath = nextProjectDirectory .. SEPERATOR_CHAR .. projectName .. ".rpp" + + if reaper.file_exists(nextProjectPath) then + projectPath = nextProjectPath + break + end + + nextSeperatorChar = string.find(directoryToSearchReverse, SEPERATOR_CHAR, nextSeperatorChar + 1) + + if not nextSeperatorChar then + break + end + + nextProjectDirectory = string.sub(directory, 0, string.len(directory) - nextSeperatorChar) +end + +if not projectPath then + reaper.ShowMessageBox("Unable to locate project `" .. projectName .. "`", "Open In Strata: Failed", OK_MESSAGE_BOX) + return +end + +-- Open project and scroll to region -- +reaper.Main_OnCommand(41929, 0) -- opens new project tab +reaper.Main_openProject("noprompt:" .. projectPath) + +local markersAndRegions, _, _ = reaper.CountProjectMarkers(CURRENT_PROJECT) + +local regionFound = false +for i = 0, markersAndRegions - 1 do + local _, _, _, _, currentRegion, index, _ = reaper.EnumProjectMarkers3(0, i) + + if currentRegion == regionName then + reaper.GoToRegion(0, index, true) + regionFound = true + break + end +end + +if not regionFound then + reaper.ShowMessageBox("Unable move cursor to region `" .. regionName .. "`", "Open In Strata: Failed", OK_MESSAGE_BOX) +end + +local trackView = reaper.JS_Window_FindChildByID(reaper.GetMainHwnd(), TRACK_VIEW_ID) + +reaper.Main_OnCommand(40297,0) -- deselect all tracks + +local trackFound = false +for i = 0, reaper.CountTracks() - 1 do + local currentTrack = reaper.GetTrack(CURRENT_PROJECT, i) + local _, currentTrackName = reaper.GetTrackName(currentTrack) + + if currentTrackName == trackName then + reaper.SetTrackSelected(currentTrack, true) + + -- Get Y postion of track and then scroll to it + local yPosition = reaper.GetMediaTrackInfo_Value(currentTrack, "I_TCPY") + reaper.JS_Window_SetScrollPos(trackView, "v", yPosition) + + trackFound = true + break + end +end + +if not trackFound then + reaper.ShowMessageBox("Unable to scroll view to track `" .. trackName .. "`", "Open In Strata: Failed", OK_MESSAGE_BOX) +end +\ No newline at end of file