freesound
1.0A client for Freesound.org.
Common Lisp client for the Freesound API
Freesound is a large-scale collaborative database of audio recordings released under Creative Commons licenses. It offers an API for interacting with the database: searching for sounds, retrieving meta-data, accessing audio content analysis, download and upload sounds, comment, rate, and bookmark, etc.
This is a Common Lisp library for the API, created and maintained by Nuno Trocado, and released under the MIT License.
Installing and loading
With quicklisp:
(ql:quickload "freenode")
Authentication
The Freesound API offers two authentication strategies: token-based and OAuth2. The first one is simpler, but you need OAuth2 to access resources that imply a logged in user, including downloading sounds (but not lossy preview versions).
Token authentication
To use the token authentication strategy, request new API credentials at Freesound. Then you'll be shown a table with the requested credentials. Set *token*
to the alphanumeric string found in the "Client secret/Api key" column:
(setf *token* <string>)
If you save it on a ".token" file on the same directory as the freesound
system, the code will be read automatically every time the system is loaded.
OAuth2 authentication
In addition to the previous steps, find the "client id" at the same credentials table in the Freesound website. Then do:
(setf *client-id* <string>)
(oauth2-authorize)
The default browser will be opened and you'll be asked to log in and authorize the access to Freesound. The specific link will be also printed (typically to the REPL). Afterwards, you'll be redirected to another Freesound page showing you a new alphanumeric code. Copy this code and do:
(oauth2-get-tokens <code>)
This function stores the oauth2 token in *oauth2-access-token*
, which will be used in further API calls. It will also return two values: the access token itself and a refresh token. If you save the refresh token you can spare yourself (or the user of your app) the full authorization process, by using (oauth2-get-tokens <refresh token> :refresh t)
each time the authorization times out, which it does after 24 hours.
Documentation
Full documentation is here.
Refer to the Freesound API documentation for the complete description of the available resources and their request parameters and accepted values, as well as the format of the responses.
The responses obtained from Freesound are translated to Common Lisp data structures. In particular, objects like search results and instance information are parsed as hash tables.
For the request parameters, a string conforming to the API syntax is always accepted. When multiple terms are to be passed to a single parameter, lists are also accepted, and converted to the appropriate strings under the hood. Numbers are automatically parsed too.
In some cases, there are further facilities to construct parameters in a lispy way. Check the examples below and the reference.
There are also convenience functions to make it easier to perform quick queries from the REPL: print-search-result
and print-info
.
Overview and examples
Searching
Perform a text search, using the minus '-' character to exclude terms from the search:
(text-search "conga percussive -loop")
This is equivalent:
(text-search '("conga" "percussive" "-loop"))
In general, any request parameters can be passed either as a single string conforming to the API syntax, or as a list of terms.
Filter properties can be further specified with the operators :and
, :or
, :range
, :range-to
, and :range-from
. For example:
(text-search "rain"
:filter '((:tag (:and "soundscape" "forest"))
(:created (:range-from "2010-12-01T23:59:59.999Z"))
(:duration (:range 10 120))))
print-search-result
is a convenience function to pretty print the results.
Here's another example:
(print-search-result (text-search "piano"
:filter '(:duration (:range-to 2))
:sort "rating_desc"
:page-size 3
:fields '("id" "name" "analysis")
:descriptors '("lowlevel.spectral_centroid.mean"
"lowlevel.pitch.mean")))
Which prints:
Showing 3 results from a total of 943:
id: 442981
name: Sol-G.m4a
analysis: lowlevel: spectral_cent: mean: 499.9333
pitch: mean: 386.42862
id: 39210
name: Piano ff 062.wav
analysis: lowlevel: spectral_cent: mean: 1047.3967
pitch: mean: 933.2059
id: 337302
name: MSfxP6 - 183 - One Shot Sound 3
analysis: lowlevel: spectral_cent: mean: 435.96042
pitch: mean: 460.73337
As you can see, the response included the fields and descriptors chosen, and was limited to 3 results, as this was the page-size
that we specified.
The descriptors (audio features) can also be used as the search query, with content-search
:
(content-search '("lowlevel.pitch.mean" 220)
:page-size 10
:fields '("id" "tags"))
The results are sorted according to their distance from the descriptor value.
The target for content-search
can also be another sound. In this case, the target sound's descriptors will be used as the search query, but it's possible to further limit the search using :descriptors-filter
, which accepts the same constructs as :filter
in text-search
.
(content-search 39210
:descriptors-filter '(("tonal.key_key" "\"A\"")
("tonal.key_strength" (:range-from 0.8))))
Note that for parameters that must be enclosed in double-quotes, we have to escape the double-quotes, like "A"
above.
You can achieve the same kind of search with similar
.
Finally, it's also possible to search in meta-data and audio features at the same time, with combined-search
.
Sounds
Use info
to get information on a sound from the Freesound database. For example:
(info 1234 :fields "filesize")
If you're calling info
after performing a search, it's recommended that you include the fields
parameter with the search request, removing the need to make an extra query for each individual result.
print-info
is useful to quickly get the values at the REPL:
(print-info (info 213524
:fields '("name" "analysis")
:descriptors '("rhythm.bpm"
"lowlevel.mfcc.min"
"lowlevel.spectral_centroid.mean"
"tonal.hpcp_entropy.var")))
Prints:
name: 120 bpm distorded drum loop
analysis: lowlevel: spectral_cent: mean: 1313.7423
mfcc: min: (-1011.6488
-21.778429
-79.655426
-22.136934
-39.293144
-32.40432
-29.894882
-21.09641
-27.268171
-25.490017
-66.50812
-33.063526
-21.2058)
tonal: hpcp_entropy: var: 0.45190468
rhythm: bpm: 119.80438
Use preview
to download lossy versions of sounds:
(preview 678 "~/678.mp3")
And download
for other formats, e.g.:
(download 345 (merge-pathnames (gethash "name" (info 345))
(user-homedir-pathname)))
You can also upload your sounds with upload
, either describing them at the same time or using describe-sound
later. Check the list of sounds pending approval with pending-uploads
.
Note that OAuth2 authentication is required for downloading (but not with preview
) and uploading.
Other functions that operate on sounds are comment
, edit-sound-description
, bookmark
, and rate
.
Users, packs, and more
There's a range of functions that return information on a Freesound user. Check the documentation. They start with user-
.
Similarly, you can get information and operate on packs with the functions that start with pack-
.
me
returns information on the logged-in user, and descriptors
returns the available audio descriptor names, organized by category.
Contributing
Feedback, questions, bug reports, pull requests, etc. are very welcomed!
System Information
Definition Index
-
FREESOUND
Common Lisp client to the Freesound API.
-
EXTERNAL SPECIAL-VARIABLE *CLIENT-ID*
An alphanumeric string issued by Freesound, used as part of OAuth2 authentication.
-
EXTERNAL SPECIAL-VARIABLE *OAUTH2-ACCESS-TOKEN*
An alphanumeric string used as an access token for OAuth2 restricted resources. Call `oauth2-get-tokens` to initialize.
-
EXTERNAL SPECIAL-VARIABLE *OAUTH2-REFRESH-TOKEN*
An alphanumeric string used to get a new OAuth2 access token, without starting the whole authentication process. Call `oauth2-get-tokens` to initialize. To refresh the OAuth2 access token, pass this to `oauth2-get-tokens` with `:refresh t`.
-
EXTERNAL SPECIAL-VARIABLE *TOKEN*
An alphanumeric string issued by Freesound to authenticate API calls.
-
EXTERNAL FUNCTION ANALYSIS
- SOUND-ID
- &KEY
- DESCRIPTORS
- NORMALIZED
Retrieve analysis information (content-based descriptors) on SOUND-ID. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id58
-
EXTERNAL FUNCTION BOOKMARK
- SOUND-ID
- &KEY
- NAME
- CATEGORY
Bookmark an existing sound SOUND-ID. The sound will be bookmarked by the Freesound user logged in using OAuth2, therefore this method requires OAuth2 authentication. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id66
-
EXTERNAL FUNCTION COMBINED-SEARCH
- &KEY
- QUERY
- FILTER
- SORT
- TARGET
- DESCRIPTORS-FILTER
- PAGE
- PAGE-SIZE
- FIELDS
- DESCRIPTORS
- NORMALIZED
Perform a combination of text search and content search, returning a hash-table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id55 See `text-search` and `content-search`.
-
EXTERNAL FUNCTION COMMENT
- SOUND-ID
- COMMENT
Post a COMMENT to an existing sound SOUND-ID. The comment will appear to be made by the Freesound user logged in using OAuth2. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id68
-
EXTERNAL FUNCTION COMMENTS
- SOUND-ID
- &KEY
- PAGE
- PAGE-SIZE
Retrieves comments for SOUND-ID. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id60
-
EXTERNAL FUNCTION CONTENT-SEARCH
- TARGET
- &KEY
- DESCRIPTORS-FILTER
- PAGE
- PAGE-SIZE
- FIELDS
- DESCRIPTORS
- NORMALIZED
Search sounds based on their content descriptors, returning a hash-table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id54 The filter syntax described in `text-search` also applies to DESCRIPTORS-FILTER.
-
EXTERNAL FUNCTION DESCRIBE-SOUND
- UPLOAD-FILENAME
- TAGS
- DESCRIPTION
- LICENSE
- &KEY
- NAME
- PACK
- GEOTAG
Describe a previously uploaded audio file that has not yet been described. OAuth2 required. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id63 LICENSE is either one of the strings accepted by the API, or one of the following: :attribution, :attribution-noncommercial, :creative-commons.
-
EXTERNAL FUNCTION DESCRIPTORS
Information about the available audio descriptors that are extracted from Freesound sounds. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id81
-
EXTERNAL FUNCTION DOWNLOAD
- SOUND-ID
- PATHNAME
- &KEY
- IF-EXISTS
- IF-DOES-NOT-EXIST
Download SOUND-ID into PATHNAME. Keyword options are as in `open`. OAuth2 required. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id61
-
EXTERNAL FUNCTION EDIT-SOUND-DESCRIPTION
- SOUND-ID
- &KEY
- NAME
- TAGS
- DESCRIPTION
- LICENSE
- PACK
- GEOTAG
Edit the description of an already existing sound. Note that this resource can only be used to edit descriptions of sounds created by the Freesound user logged in using OAuth2. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id65 LICENSE is either one of the strings accepted by the API, or one of the following: :attribution, :attribution-noncommercial, :creative-commons.
-
EXTERNAL FUNCTION INFO
- SOUND-ID
- &KEY
- FIELDS
- DESCRIPTORS
- NORMALIZED
Retrieve information about SOUND-ID. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id57
-
EXTERNAL FUNCTION ME
Information about the user that is logged in using the OAuth2 procedure. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id80
-
EXTERNAL FUNCTION OAUTH2-AUTHORIZE
- &OPTIONAL
- CLIENT-ID
As the first step of OAuth2 authentication, open the default browser on a Freesound page, where users are prompted to log in and asked to give permission for the application. The url is also printed to standard output.
-
EXTERNAL FUNCTION PACK-DOWNLOAD
- PACK-ID
- PATHNAME
- &KEY
- IF-EXISTS
- IF-DOES-NOT-EXIST
Download PACK-ID into PATHNAME. Keyword options are as in `open`. OAuth2 required. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id78
-
EXTERNAL FUNCTION PACK-INSTANCE
- PACK-ID
Retrieve information about the pack PACK-ID. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id76
-
EXTERNAL FUNCTION PACK-SOUNDS
- PACK-ID
- &KEY
- PAGE
- PAGE-SIZE
- FIELDS
- DESCRIPTORS
- NORMALIZED
Retrieve information about the sounds included in the pack PACK-ID. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id77
-
EXTERNAL FUNCTION PENDING-UPLOADS
Retrieve a list of audio files uploaded by the Freesound user logged in using OAuth2 that have not yet been described, processed or moderated. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id64
-
EXTERNAL FUNCTION PREVIEW
- SOUND-ID
- PATHNAME
- &KEY
- FORMAT
Download a lossy version of SOUND-ID, writing it to PATHNAME. FORMAT is either :hq-mp3, :hq-ogg, :lq-mp3, :lq-ogg, where "hq" is higher quality and "lq" lower quality.
-
EXTERNAL FUNCTION PRINT-INFO
- INFO
- &OPTIONAL
- STREAM
Pretty print INFO, which is the response to `info` (sound instance) or to `analysis`.
-
EXTERNAL FUNCTION PRINT-SEARCH-RESULT
- SEARCH-RESULT
- &OPTIONAL
- STREAM
Pretty print SEARCH-RESULT, a sound list response.
-
EXTERNAL FUNCTION RATE
- SOUND-ID
- RATING
Rate an existing sound SOUND-ID with RATING, between 0 and 5 (where 5 is the maximum). The sound will be rated by the Freesound user logged in using OAuth2. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id67
-
EXTERNAL FUNCTION SIMILAR
- SOUND-ID
- &KEY
- DESCRIPTORS-FILTER
- PAGE
- PAGE-SIZE
- FIELDS
- DESCRIPTORS
- NORMALIZED
Retrieve sounds similar to SOUND-ID, returning a hash table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id59 The filter syntax described in `text-search` also applies to DESCRIPTORS-FILTER.
-
EXTERNAL FUNCTION TEXT-SEARCH
- QUERY
- &KEY
- FILTER
- SORT
- GROUP-BY-PACK
- PAGE
- PAGE-SIZE
- FIELDS
- DESCRIPTORS
- NORMALIZED
Search sounds by matching their tags and other kids of metadata, returning a hash-table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id53 FILTER is either a string conforming to the API syntax, or a list of key/value pairs. For example: (text-search "trumpet" :filter '((:type "ogg") (:channels 2))) Each filter property can be further specified with the operators :and, :or, :range, :range-to, and :range-from. For example: (text-search "rain" :filter '((:tag (:and "soundscape" "forest")) (:created (:range-from "2010-12-01T23:59:59.999Z")) (:duration (:range 10 120))))
-
EXTERNAL FUNCTION UPLOAD
- FILE
- &KEY
- NAME
- TAGS
- DESCRIPTION
- LICENSE
- PACK
- GEOTAG
Upload an audio FILE into Freesound and (optionally) describe it. If a description is intended, all of TAGS, DESCRIPTION and LICENSE are required. OAuth2 required. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id62 LICENSE is either one of the strings accepted by the API, or one of the following: :attribution, :attribution-noncommercial, :creative-commons.
-
EXTERNAL FUNCTION USER-BOOKMARK-CATEGORIES
- USERNAME
- &KEY
- PAGE
- PAGE-SIZE
Retrieve the bookmark categories uploaded by Freesound user USERNAME, returning a hash table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id73
-
EXTERNAL FUNCTION USER-PACKS
- USERNAME
- &KEY
- PAGE
- PAGE-SIZE
Retrieve information about the packs uploaded by Freesound user USERNAME, returning a hash table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id72
-
EXTERNAL FUNCTION USER-SOUNDS
- USERNAME
- &KEY
- PAGE
- PAGE-SIZE
- FIELDS
- DESCRIPTORS
- NORMALIZED
Retrieve information about the sounds uploaded by Freesound user USERNAME, returning a hash table with the sound list response. API documentation: https://freesound.org/docs/api/resources_apiv2.html#id71
-