Error

When it comes to the mdfind command one of my variables, (“aValue”, holds between 12-200 values) is not looping through its list, its just counting the amount of items its storing and using that as 1 value for the calculation. Can anyone explain where Im going wrong?



use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use script "Metadata Lib" version "2.0.0"
use mdLib : script "Metadata Lib" version "2.0"
property twelfth_root_2 : (2 ^ (1 / 12))


tell application "Finder"
	delete (every item of folder "Mojave:Users:dh:Music:Samples:EXS24:ESX242:autocrop:Term:")
end tell




display dialog "Choose fundemental frequency in Hertz" default answer ""


if text returned of result contains "A" then
	set fRoot to 440.0
else if text returned of result contains "B" then
	set fRoot to 493.88
else if text returned of result = "Bb" then
	set fRoot to 466.16
else if text returned of result contains "C" then
	set fRoot to 523.25
else if text returned of result contains "Ab" then
	set fRoot to 415.3
else if text returned of result contains "G" then
	set fRoot to 392.0
else if text returned of result contains "Gb" then
	set fRoot to 369.99
else if text returned of result contains "F" then
	set fRoot to 349.23
else if text returned of result contains "E" then
	set fRoot to 329.63
else if text returned of result contains "Eb" then
	set fRoot to 311.13
else if text returned of result contains "D" then
	set fRoot to 293.66
else if text returned of result contains "Db" then
	set fRoot to 277.18
else
	set fRoot to text returned of result
end if

set presets to {"b9", "9th", "m3", "3rd", "4th", "Dim5", "5th", "Aug5", "6th", "7th", "m7", "Oct"}





set theMode to (choose from list presets with prompt "Choose a character:" with multiple selections allowed)
if (theMode is false) then return -- user cancelled

set frequencies to {}
repeat with semitones from 1 to (count presets)
	if (theMode contains {item semitones of presets}) then
		set frequency to (round (fRoot * (twelfth_root_2 ^ semitones)))
		set end of frequencies to ¬
			{((round ((frequency / 256) / 5)) * 5), ((round ((frequency / 128) / 5)) * 5), ((round ((frequency / 64) / 5)) * 5), ((round ((frequency / 32) / 5)) * 5), ((round ((frequency / 16) / 5)) * 5), ((round ((frequency / 8) / 5)) * 5), ((round ((frequency / 4) / 5)) * 5), ((round ((frequency / 2) / 5)) * 5), ((round (frequency / 5)) * 5), ((round ((frequency * 2) / 5)) * 5), ((round ((frequency * 4) / 5)) * 5), ((round ((frequency * 8) / 5)) * 5), ((round ((frequency * 16) / 5)) * 5), ((round ((frequency * 32) / 5)) * 5), ((round ((frequency * 64) / 5)) * 5), ((round ((frequency * 128) / 5)) * 5), ((round ((frequency * 256) / 5)) * 5), ((round ((frequency * 512) / 5)) * 5)}
		
		
		
	end if
end repeat





set TheSearchPath to quoted form of POSIX path of "/Users/dh/Music/Samples/EXS24/ESX242/autocrop/Data"
set TheDestPath to quoted form of POSIX path of "/Users/dh/Music/Samples/EXS24/ESX242/autocrop/Term"

set aValue to ((current application's class "NSArray"'s arrayWithArray:(frequencies))'s valueForKeyPath:("@unionOfArrays.self")) as list


repeat with aValue from 1 to (count of frequencies) as text
	
	set theSearch to aValue
	
	set theResult to paragraphs of (do shell script "mdfind -onlyin " & TheSearchPath & ¬
		" 'kMDItemFSName == \"*" & theSearch & "." & "0" & "Hz" & "*\"'") ¬
		
end repeat
repeat with i from 1 to count of theResult
	if (count of theResult) is 1 and item 1 of theResult is "" then exit repeat --no matches
	
	set the PosixFile to item i of theResult
	try
		do shell script "cp -f " & quoted form of PosixFile & space & TheDestPath
	end try
	
end repeat

delay 5

-- Strip Suffix of CSV

set sFolder to "Mojave:Users:dh:Music:Samples:EXS24:ESX242:autocrop:Term:"

tell application "Finder"
	set fLst to (every item in folder sFolder whose kind is not "Folder") as alias list
	if fLst is {} then return
	
	repeat with anItem in fLst
		set name_ext to anItem's name
		set ext to anItem's name extension
		if (offset of "." in name_ext) > -18 is true then
			set prefix to (characters 1 thru -18 of name_ext) as text
			if not ext = "" then set ext to ""
			set name of anItem to prefix & ext
		end if
	end repeat
	return
end tell




set thePrefix to "Mojave:Users:dh:Music:Samples:EXS24:ESX242:autocrop:Term:" whose kind is not "Folder" as list
set wavSearchPath to quoted form of POSIX path of "/Users/dh/Music/Samples/EXS24/ESX242/autocrop/files"
set aliasDestPath to quoted form of POSIX path of "/Users/dh/Music/Samples/EXS24/ESX242/autocrop/alias"

repeat with thePrefix from 1 to (count of theResult) as text
	
	set wavSearch to (thePrefix) -- "yourSearchstring" --place your sample-searchstring here to test the search
	
	set theAlias to paragraphs of (do shell script "mdfind -onlyin " & wavSearchPath & " 'kMDItemFSName == ¬
		\"*" & wavSearch & "*\"'") ¬
		
end repeat
repeat with i from 1 to count of theResult
	if (count of theResult) is 1 and item 1 of theResult is "" then exit repeat
	
	set the PosixFile to item i of theResult
	try
		do shell script "cp -f " & quoted form of PosixFile & space & TheDestPath
	end try
	result
end repeat

-- tell application "Finder"
-- 	delete (every item of folder "Mojave:Users:dh:Music:Samples:EXS24:ESX242:autocrop:alias:")
-- end tell
-- end run

You don’t say what the error is.

Needle, meet haystack.

However… on the wild assumption that the error is

Syntax Error
Expected end of line, etc, but found
identifier

OK

then

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use script "Metadata Lib" version "2.0.0"
use mdLib : script "Metadata Lib" version "2.0"
property twelfth_root_2 : (2 ^ (1 / 12))

-- clean up from previous session

tell application "Finder"
	delete (every item of folder "Mojave:Users:dh:Music:Samples:EXS24:ESX242:autocrop:alias:")
end tell


-- setting the fundamental frequency, tempered scale options & defining presets

display dialog "Choose fundamental frequency in Hertz" default answer ""-- sp fundamental

Will at least let the first few lines of your script compile.

Once you get past that…

display dialog "Choose fundamental frequency in Hertz" default answer "" --sp fundamental
--user inputs "Bb"

if text returned of result contains "A" then
	set fRoot to 440.0
else if text returned of result contains "B" then
	set fRoot to 493.88 
else if text returned of result contains "Bb" then
	set fRoot to 466.16
else if text returned of result contains "C" then
	set fRoot to 523.25
else if text returned of result contains "Ab" then
	set fRoot to 415.3
else if text returned of result contains "G" then
	set fRoot to 392.0
else if text returned of result contains "Gb" then
	set fRoot to 369.99
else if text returned of result contains "F" then
	set fRoot to 349.23
else if text returned of result contains "E" then
	set fRoot to 329.63
else if text returned of result contains "Eb" then
	set fRoot to 311.13
else if text returned of result contains "D" then
	set fRoot to 293.66
else if text returned of result contains "Db" then
	set fRoot to 277.18
else
	set fRoot to text returned of result

-- result is 493.88
end if

If you expect the user to input “Bb” and the result to be 466.16 then you’ll have to rethink the section above. The result of the input “Bb” contains “B”, so you’ll get 493.88.

And if the user inputs “SYXKSYXHXHXHXHX” then fRoot will be just that.

Oh right, sorry. i see what youre saying

The input

Thanks for pointing that out.

This works

else if text returned of result = “Bb” then
set fRoot to 466.16

Consider this for user friendliness, manageability, simplicity. It’s what we did before with the duck, the lobster, the moth and the onion man. Look back over that if you don’t understand how it works.

This puts the fundamental frequencies into a list, and in a logical sequence rather than jumbled up. Rather than hoping that the user will input a valid fundamental frequency (instead of “PLPLPOOKLKO$$$%”) it only allows her to specify one of the fundamental frequencies that you want to work with. If she doesn’t like that, she can cancel.

I have matched the fundamental frequencies to the fRoots in your original script. You will have to double check if they are correctly matched. I have a very limited knowledge of musical theory but your value for C looks wrong to me.

set FundamentalFrequencies to {"C", "D flat", "D natural", "E flat", "E natural", "F", "G flat", "G natural", "A flat", "A natural", "B flat", "B natural"}

set fRoots to {423.25, 277.18, 283.66, 311.13, 329.63, 349.23, 369.99, 392.0, 416.3, 440.0, 466.16, 493.88}

set chosenFundamental to (choose from list FundamentalFrequencies with prompt "Choose a fundamental frequency:")
if chosenFundamental = false then return
set FrequencyCounter to 1
repeat with EachFrequency in FundamentalFrequencies
	if chosenFundamental as text = EachFrequency as text then
		set fRoot to item (FrequencyCounter) of fRoots
		exit repeat
	else
		set FrequencyCounter to FrequencyCounter + 1
	end if
end repeat
display dialog "The root frequency of " & EachFrequency & " is " & fRoot

Once you have got your head around how this works, and why it works, then move on.

HI Hubert,

Thank you very much. Im pretty sure all the frequency readings are correct, but i’ll check them again. I added the tempered scale if else statements a couple of weeks ago, in the event the results needed to cohere with the tempered scale, i haven’t tried to condense the script content down, and coding is a new thing for me, but i think i know how to get it down to a couple of lines. To avoid writing flat and natural out, the if else statements, when using = as opposed to “containing” allows you to use “B” and “Bb” without one being confused for the other

Its not that I dont understand the way of the moth the lobster and the onion man and I understand what you are saying about user friendliness, but im the user and as friendly as the 12 note western scale may seem, I need more detail, and want to work in Hertz. 100 cents make up a semitone. A Cent is a logarithmic unit of measure of an interval, and that is a dimensionless “frequency ratio” of f2 / f1, , not all sounds adhere to the structure of the tempered scale, im going to implement an option to drop in samples that will be analysed returning harmonically compatible options from the sample bank, their content may not conform to the tempered scale so yeah i want to be able to work mainly in hertz rather than in semitones

worked that out - set theRound to (round (x / 5)) * 5

One of the things I would like to work out after ive fixed the variable issue, is how to use the round command in AS to round the frequency calculations off to the nearest 5.0 instead of 1

A deviation of 2.5hz each side of the reading isnt really noticeably audible and in turn would allow for more options in the sample bank.

Ive flattened the list using the 3rd line in and “theValues” is storing all the info i need in one list

But when it comes to running the mdfind command, rather than looping each value in the list
say there are 159 items in the list, its taking the number 159 and using that as a value to run the mdfind command. Returning CSV results containing 159 ie : Bassdrum34.f0 - 159.0Hz , triangle12.f0 - 59.0Hz , shaker400.f0 - 1059.0Hz Any idea how i can get it to process each item as i thought the script below would?


-- "frequencies" variable stores lists of lists containing multiple values that represent frequencies in Hertz 
-- the directory of CSV files to be cross referenced and matched with the values in the list "the values"
set TheSearchPath to quoted form of POSIX path of "/Users/dh/Music/Samples/EXS24/ESX242/autocrop/Data" 

-- the temp folder a copy of all the matched CSV files will be moved to
set TheDestPath to quoted form of POSIX path of "/Users/dh/Music/Samples/EXS24/ESX242/autocrop/Term" 

-- flattening the frequencies list of lists
-- set aValue to {}, {}}
set theValues to ((current application's class "NSArray"'s arrayWithArray:(frequencies))'s valueForKeyPath:("@unionOfArrays.self")) as list

-- not sure if this is whats causing the issue, is aValue just counting the items  of the theValues and using that number as its value in the mdfind command below?
repeat with aValue from 1 to (count of theValues)
	
	
	
	set theResult to paragraphs of (do shell script "mdfind -onlyin " & TheSearchPath & " 'kMDItemFSName == \"*" & aValue & "." & "0" & "Hz" & "*\"'")
end repeat
repeat with i from 1 to count of theResult
	if (count of theResult) is 1 and item 1 of theResult is "" then exit repeat 
	
	set the PosixFile to item i of theResult
	try
		do shell script "cp -f " & quoted form of PosixFile & space & TheDestPath
	end try
	
end repeat

I’ll continue to do my best to help because I love music and musicians and it would be great if it worked for you. Forgive me if I sound impatient from time to time.

Could you post a small sample of your .csv file (including the header if there is one, plus three or four rows) and the actual names of the sample files that correspond to it?

I suspect that all the mdFind stuff and murky incantations like

set theValues to ((current application's class "NSArray"'s arrayWithArray:(frequencies))'s valueForKeyPath:("@unionOfArrays.self")) as list

are probably unnecessary to get this working. Do you understand what it means? I sure as heck don’t :confused:

If you can offer a clear description of what you are trying to achieve, with what input and with what data sources, it may be possible to help, or to re-think.

A couple more thoughts for now…

You may be the only user, but you should be friendly to yourself. You’re going to be using this script repeatedly. Why make it error-prone? When I write scripts they’re almost always for my own use, but I always try to write them in a way that stops me from making inadvertent mistakes.

If you haven’t already, take some time to read the AppleScript Language Guide: https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html.

And Happy New Year!

hubert0

I might be biting off a bit more than i could chew attempting ASObjC, it would probably take me months i’ve only been learning AS for a month and am having to reach out for help with that. I’ve just started learning C++ and understand bits of ASObjC and have started toying with JUCE., AS may not be the most robust of languages for what im trying to achieve, ive discovered it doesnt do that well handling 10s of 1000s of files at a time, but at this stage the benefits of trying to finish this with ASObjC would most likely be overshadowed by the cons and the steep learing curve. I dont know maybe theres enough resources out there to make it a realistic and not take me forever. Though i’ll never know if i dont try. I didnt think JSON and csv’s were compatible, ive been messing around with pandas and bit and python is doing quite a bit of heavy lifting.

I enjoy it a lot, I have been investing a lot of time and effort iinto learning and am always keen too learn more so welcome any suggestions.i really appreciate how forthcoming, helpful and generous with their own time people have been on here, its heartwarming, but i have to say, if im honest i came on here for help because i was starting to actually get really depressed, when i hit a dead end, searching online for days at a time without getting anywhere. I really hope someone can help get me through this issue with the variable loop, its driving me potty