add: purest_json lib
This commit is contained in:
1 parent
e29aa19b01
commit
f9badbe6f6
69 files changed
+6421
No files matched your search
@@ -0,0 +1,315 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>
|
||||
Using JSON Data as Pitch Generator
|
||||
</title>
|
||||
<style>
|
||||
/* Page tweaks */
|
||||
.preview-page {
|
||||
margin-top: 64px;
|
||||
margin-bottom: 21px;
|
||||
}
|
||||
/* User-content tweaks */
|
||||
.timeline-comment-wrapper > .timeline-comment:after,
|
||||
.timeline-comment-wrapper > .timeline-comment:before {
|
||||
content: none;
|
||||
}
|
||||
/* User-content overrides */
|
||||
.discussion-timeline.wide {
|
||||
width: 920px;
|
||||
}
|
||||
</style>
|
||||
<link href="style.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<div class="preview-page" data-autorefresh-url="" id="preview-page">
|
||||
<main id="js-repo-pjax-container">
|
||||
<div class="clearfix new-discussion-timeline container-xl px-3 px-md-4 px-lg-5">
|
||||
<div class="repository-content">
|
||||
<div class="clearfix">
|
||||
<div class="Layout Layout--flowRow-until-md Layout--sidebarPosition-end Layout--sidebarPosition-flowRow-end">
|
||||
<div class="Layout-main">
|
||||
<div class="Box md Box--responsive" id="readme">
|
||||
<div class="Box-header d-flex border-bottom-0 flex-items-center flex-justify-between color-bg-default rounded-top-2">
|
||||
<div class="d-flex flex-items-center">
|
||||
<h2 class="Box-title">
|
||||
Using JSON Data as Pitch Generator
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Box-body px-5 pb-5">
|
||||
<article class="markdown-body entry-content container-lg" id="grip-content">
|
||||
<p>
|
||||
This tutorial will show you, how you can get data from a simple RESTful webservice and generate sound from it.
|
||||
</p>
|
||||
<p>
|
||||
In this tutorial, I will use the following notation:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>
|
||||
[my object]
|
||||
</code>
|
||||
: an object with the name "my-object".
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
[my own message(
|
||||
</code>
|
||||
: a message with the content "my own message".
|
||||
</li>
|
||||
</ul>
|
||||
<h2>
|
||||
<a aria-hidden="true" class="anchor" href="#getting-the-data" id="user-content-getting-the-data">
|
||||
<span aria-hidden="true" class="octicon octicon-link">
|
||||
</span>
|
||||
</a>
|
||||
Getting the Data
|
||||
</h2>
|
||||
<p>
|
||||
This example gets the conversion rates between US Dollar und Euro from the
|
||||
<a href="https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/usd.xml" rel="nofollow">
|
||||
European central bank
|
||||
</a>
|
||||
, which on the server is converted from XML to JSON.
|
||||
</p>
|
||||
<p>
|
||||
<a rel="noopener noreferrer nofollow" target="_blank">
|
||||
<img alt="The patch" src="currency-full.png" style="max-width: 100%;"/>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
The data from the script on the website looks something like this:
|
||||
</p>
|
||||
<pre><code>[
|
||||
{"day":"1999-01-04","rate":1.1789},
|
||||
{"day":"1999-01-05","rate":1.179},
|
||||
{"day":"1999-01-06","rate":1.1743},
|
||||
{"day":"1999-01-07","rate":1.1632}
|
||||
]
|
||||
</code></pre>
|
||||
<p>
|
||||
When the data is received, the returned value is fed into
|
||||
<code>
|
||||
[json-decode]
|
||||
</code>
|
||||
. As the symbol atom from
|
||||
<code>
|
||||
[rest]
|
||||
</code>
|
||||
will be a JSON array, we will get messages for each JSON object on the middle outlet followed by a bang on the left outlet.
|
||||
</p>
|
||||
<p>
|
||||
A sequence of messages for an object looks like this:
|
||||
</p>
|
||||
<pre><code>list day 1999-01-04
|
||||
list rate 1.1789
|
||||
</code></pre>
|
||||
<h2>
|
||||
<a aria-hidden="true" class="anchor" href="#storing-the-data" id="user-content-storing-the-data">
|
||||
<span aria-hidden="true" class="octicon octicon-link">
|
||||
</span>
|
||||
</a>
|
||||
Storing the Data
|
||||
</h2>
|
||||
<p>
|
||||
This section discusses the operations in the subpatch
|
||||
<code>
|
||||
[pd store-data]
|
||||
</code>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
<a rel="noopener noreferrer nofollow" target="_blank">
|
||||
<img alt="pd process-data" src="currency-data-processing.png" style="max-width: 100%;"/>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
In this subpatch, the incoming lists from
|
||||
<code>
|
||||
[json-decode]
|
||||
</code>
|
||||
are taken and packed into one list for each JSON object in the array.
|
||||
</p>
|
||||
<p>
|
||||
First, we remove the
|
||||
<code>
|
||||
list
|
||||
</code>
|
||||
prefix from each message, then pack those messages, and use the bang message from the left outlet of
|
||||
<code>
|
||||
[json-decode]
|
||||
</code>
|
||||
that is emitted after each decoded array member to trigger the output of
|
||||
<code>
|
||||
[pack]
|
||||
</code>
|
||||
. The transformed message for each JSON object then looks like:
|
||||
</p>
|
||||
<pre><code>0 1999-01-04 1.1789
|
||||
</code></pre>
|
||||
<p>
|
||||
Notes:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
The date will not come out as a symbol. Conversion is done with a
|
||||
<code>
|
||||
[symbol]
|
||||
</code>
|
||||
object.
|
||||
</li>
|
||||
<li>
|
||||
Each output from
|
||||
<code>
|
||||
[pack f s f]
|
||||
</code>
|
||||
starts with a
|
||||
<code>
|
||||
0
|
||||
</code>
|
||||
, as we only use the bang on the first inlet of
|
||||
<code>
|
||||
[pack]
|
||||
</code>
|
||||
to trigger the output.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
We then use
|
||||
<code>
|
||||
[text]
|
||||
</code>
|
||||
to store the value. We use a very high number for the position
|
||||
<code>
|
||||
1e+15
|
||||
</code>
|
||||
, to ensure that new values are appended without a counter before.
|
||||
</p>
|
||||
<h2>
|
||||
<a aria-hidden="true" class="anchor" href="#sequencing-the-values" id="user-content-sequencing-the-values">
|
||||
<span aria-hidden="true" class="octicon octicon-link">
|
||||
</span>
|
||||
</a>
|
||||
Sequencing the values
|
||||
</h2>
|
||||
<p>
|
||||
This section discusses the operations in the subpatch
|
||||
<code>
|
||||
[pd stepper]
|
||||
</code>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
<a rel="noopener noreferrer nofollow" target="_blank">
|
||||
<img alt="pd stepper" src="currency-stepper.png" style="max-width: 100%;"/>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
This subpatch starts a
|
||||
<code>
|
||||
[metro]
|
||||
</code>
|
||||
after all data is stored. This is basically just the sequencer example from the
|
||||
<code>
|
||||
[text]
|
||||
</code>
|
||||
help file.
|
||||
</p>
|
||||
<h2>
|
||||
<a aria-hidden="true" class="anchor" href="#generating-sound" id="user-content-generating-sound">
|
||||
<span aria-hidden="true" class="octicon octicon-link">
|
||||
</span>
|
||||
</a>
|
||||
Generating sound
|
||||
</h2>
|
||||
<p>
|
||||
Sound generation is the bottom part of the main patch.
|
||||
</p>
|
||||
<p>
|
||||
The exchange rates between US Dollar and Euro is varying very narrowly around 1. The value is multiplied by a fixed number and with an offset interpreted as MIDI notes, such that a change of 0.03 in the exchange rate will result in a change of the tone of 1 semitone.
|
||||
</p>
|
||||
<p>
|
||||
Different data might benefit from other scaling methods, linear, logarithmic, exponential, or poynomial.
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function showCanonicalImages() {
|
||||
var images = document.getElementsByTagName('img');
|
||||
if (!images) {
|
||||
return;
|
||||
}
|
||||
for (var index = 0; index < images.length; index++) {
|
||||
var image = images[index];
|
||||
if (image.getAttribute('data-canonical-src') && image.src !== image.getAttribute('data-canonical-src')) {
|
||||
image.src = image.getAttribute('data-canonical-src');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToHash() {
|
||||
if (location.hash && !document.querySelector(':target')) {
|
||||
var element = document.getElementById('user-content-' + location.hash.slice(1));
|
||||
if (element) {
|
||||
element.scrollIntoView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function autorefreshContent(eventSourceUrl) {
|
||||
var initialTitle = document.title;
|
||||
var contentElement = document.getElementById('grip-content');
|
||||
var source = new EventSource(eventSourceUrl);
|
||||
var isRendering = false;
|
||||
|
||||
source.onmessage = function(ev) {
|
||||
var msg = JSON.parse(ev.data);
|
||||
if (msg.updating) {
|
||||
isRendering = true;
|
||||
document.title = '(Rendering) ' + document.title;
|
||||
} else {
|
||||
isRendering = false;
|
||||
document.title = initialTitle;
|
||||
contentElement.innerHTML = msg.content;
|
||||
showCanonicalImages();
|
||||
}
|
||||
}
|
||||
|
||||
source.onerror = function(e) {
|
||||
if (e.readyState === EventSource.CLOSED && isRendering) {
|
||||
isRendering = false;
|
||||
document.title = initialTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onhashchange = function() {
|
||||
scrollToHash();
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
scrollToHash();
|
||||
}
|
||||
|
||||
showCanonicalImages();
|
||||
|
||||
var autorefreshUrl = document.getElementById('preview-page').getAttribute('data-autorefresh-url');
|
||||
if (autorefreshUrl) {
|
||||
autorefreshContent(autorefreshUrl);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user