1

I'm using an application that loads the contents of a folder of audio samples for my use. The samples I want to use however, are scattered amongst many folders on my machine, and I don't want to copy them all into a single folder first.

Aliases work just fine, and I was able to make symlinks of all the desired files, put them in a single folder, and load that folder. Excellent solution, except for one thing.

I'm going to be adding more files over time that meet the criteria I use for this application. I would love to be able to use a dynamic folder that would essentially be what "Smart Folders" are, except a real folder. A Mac "Smart Folder" is not actually a folder at all, but really just creates a "SavedSearch" file, which is unreadable except by the Finder so my application can't see into it.

Is it possible to create a true dynamic folder that will just update as the filesystem changes? Or maybe being realtime would be too much of a strain, so on a schedule? I could see maybe concocting something in Automator but... I dunno sounds a bit heavy. Love to know if there's a better way!

  • A user-friendly app wouldn't require this: either links to the samples or sample library are collected in a project file (or folder) or - if required - the samples are exported/copied to a user specified folder from inside the app. Please add the app name! – klanomath Apr 16 '17 at 21:11
  • It's actually a plugin called DrumFoldr, and I'm using it inside the Ableton Live host software. This is not an issue of "user friendliness". This plugin adds an extremely useful feature to Ableton, since it is not possible to load a sampler with more than 128 files otherwise. This really has nothing to do with the software in question. I need truly dynamic, updating folders and I'm asking if that is possible and if so, how. – Jonathan van Clute Apr 16 '17 at 21:13
  • With "user friendly" I meant: get beyond the restrictions of the hierarchical file system and choose a more database driven approach. Partially this is already implemented in macOS with the (Spotlight)-API. If the host app (or a plugin) doesn't access this API, usually the "project file" or a file/folder based (e.g. "Collect for Output" (QuarkXPress)) method is chosen. What are your criteria to choose a sample and how do you browse them? You can always build an (Automator) service: link sound file(s) to specific folder(s). – klanomath Apr 16 '17 at 21:51
  • In Ableton Live I can load a drum machine up with samples - up to 128 of them. That is the maximum possible by design. But through a plugin it is possible to load any number (or a whole folder in this case), and simply scroll through them with a knob as your music plays, so you can hear the different samples in context. The plugin allows me to select a folder of samples, but it must be a real folder (or alias), not a SavedSearch file. I would like a dynamic folder containing all audio files under 2 seconds in length and a "Smart Folder" won't work. Hope that makes sense. – Jonathan van Clute Apr 17 '17 at 1:12
  • I got that already thanx ;-) (because I visited the ldmdesign site and read the plugin description). The number of samples seems to be limited to 5000 items/folder though. – klanomath Apr 17 '17 at 1:18
2

I have found a solution to create a dynamic "soft link" folder:

Preface:

  • $HOME is the result of the environmental variable HOME here. When you log in as user example_user, $HOME is then the path to the home folder of example_user: /Users/example_user. If $HOME appears in the text below you have to replace it yourself with /Users/your_user_name/ (e.g. saving the launch agent). If $HOME appears in a code box below (e.g. in the shell script) it will automatically expanded to your home folder by the (bash) shell while executing the script.
  • mdimport -A|sed $'s/\t\t/;/g;s/(null)//g'|tr -d \' shows a lot of metadata attributes to choose from as search criteria (e.g. kMDItemAudioBitRate or kMDItemDurationSeconds)
  • mdls /path/to/file lists all metadata attributes of a chosen file

Creating a dynamic link folder:

  • Create a shell script samples.sh in $HOME/bin/sh/ with the following content:

    #!/bin/bash
    
    # Define folders
    # Source folder (including files in subfolders)
    MusicSamples=$HOME/Music/Samples
    # Destination folder
    DrumFoldr=$HOME/Desktop/Samples
    
    # Remove orphaned soft links in the destination folder
    find $DrumFoldr -type l -exec sh -c 'for x; do [ -e "$x" ] || rm "$x"; done' _ {} +
    
    # Add soft links in destination folder depending on some criteria (here: BitRate and UserTag)
    for File in $(mdfind -onlyin $MusicSamples 'kMDItemAudioBitRate >= "44000"  && _kMDItemUserTags = "Sample"')
    do
        ln -s $File $DrumFoldr
    done
    
    # Remove soft links in the destination folder depending on some criteria (removing UserTag from original file)
    for File in $(mdfind -onlyin $MusicSamples '_kMDItemUserTags != "Sample"')
    do
        filename=$(basename "$File")
        rm $DrumFoldr/$filename
    done
    

    In the shell script define your music folder containing the sample files (in my example that's a Samples folder in the Music folder) and the "DrumFoldr" containing the soft links later (in my example that's a Samples folder on my Desktop).

    Now choose some Spotlight search criteria (in my example I have chosen the bit rate and a user defined tag "Sample" - you can define user tags by right-clicking a file > Tags... and adding a tag by just writing something. The user defined tag is then available for other files and folders.

    enter image description here

    The above shell script will add only files with a sample rate of 44000 or higher and (this is a logical and!) with the user tag "Sample" as soft link to the DrumFoldr folder. So the destination folder will not contain links to files without the Sample tag but with a sample rate of 96k or files with the Sample tag but without a kMDItemAudioBitRate (like txt files or pdfs). It also does some cleansing in the DrumFoldr folder.

    BTW: the music length can be searched/determined by using the key kMDItemDurationSeconds: kMDItemDurationSeconds <= "2".

  • Create a file usr.samplesync.plist in $HOME/Library/LaunchAgents (that means: /Users/<username>/Library/LaunchAgents/) with the content:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>usr.samplesync</string>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/bash</string>
            <string>/Users/<username>/bin/sh/samples.sh</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StartInterval</key>
        <integer>10</integer>
    </dict>
    </plist>
    

    Replace <username> by your short user name. The shell script will be executed every 10 seconds. You can increase the interval depending on your needs and environment to higher values (e.g. 60 = 1 minute or 600 = 10 minutes)

  • Load the launch agent with:

    launchctl load $HOME/Library/LaunchAgents/usr.samplesync.plist
    

If you want to save the shell script somewhere else you have to apply the path in the plist accordingly.


Caveats:

  • the original sample files mustn't contain spaces in their paths or file names (I try to solve this restriction later)
  • the original sample files mustn't be moved or the removing of the user tag won't delete the soft link

Things to improve:

  • don't create a soft link if a proper one already exists
  • Wow very cool!! For myself I would not want the tag requirement as that's something I would then have to manually add every time I got more samples. Also many samples will have spaces in the names. Am I correct that this is actually creating symlinks of every file in my entire samples folder (recursively?), and deleting the ones that don't meet the criteria? That's a bit heavy because my "samples" folder also contains LOTS of other files (synth patches, PDFs, nested folders, etc.) so this will be a TON of creation/deletion. Great answer but I'm not sure I could use it in my current setup. – Jonathan van Clute Apr 17 '17 at 14:09
  • Rats, the script can't handle my drive having a space in the name even though it's escaped: MusicSamples=/Volumes/AUDIO_2TB/Audio\ Libraries/_Free/Audio/ – Jonathan van Clute Apr 17 '17 at 17:02
  • @JonathanvanClute Tried that - shouldn't work! I also tested an array construction which also failed, I think I will later ask a question here regarding the problem. – klanomath Apr 17 '17 at 18:04
  • Wow interesting... it does work in that it creates a bunch of files, and even then deletes the ones missing the tag (which is all of them in my case), but what it creates is all wrong and aren't even valid at all. Very odd. Here is my current code: https://pastebin.com/FQ3uT8XF – Jonathan van Clute Apr 17 '17 at 18:09
  • OK I have taken spaces out of the equation as a test, and the script works fine, the resulting symlinks are correct and usable. So this is just to confirm that handling spaces in the paths appears to be the only issue. – Jonathan van Clute Apr 18 '17 at 1:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .