{"id":166,"date":"2012-02-22T13:27:33","date_gmt":"2012-02-22T11:27:33","guid":{"rendered":"http:\/\/www.joanillo.org\/?p=166"},"modified":"2020-09-14T13:28:52","modified_gmt":"2020-09-14T11:28:52","slug":"jplay-sndfile-una-aplicacio-educativa-per-a-processament-digital-del-senyal","status":"publish","type":"post","link":"https:\/\/www.joanillo.org\/?p=166","title":{"rendered":"jplay-sndfile: una aplicaci\u00f3 educativa per a Processament Digital del Senyal"},"content":{"rendered":"<p><a href=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/02\/pic-digitalsignal.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/02\/pic-digitalsignal-300x183.jpg\" alt=\"\" title=\"pic-digitalsignal\" width=\"300\" height=\"183\" class=\"alignright size-medium wp-image-594\"><\/a><strong>jplay-sndfile<\/strong> \u00e9s una aplicaci\u00f3 que he estat programant la \u00faltima setmana i que t\u00e9 un car\u00e0cter did\u00e0ctic. B\u00e0sicament \u00e9s un reproductor de fitxers d&#8217;\u00e0udio, que a m\u00e9s pot aplicar un canvi de freq\u00fc\u00e8ncia, i tamb\u00e9 pot fer un escombrat continu de freq\u00fc\u00e8ncies sobre la mostra d&#8217;\u00e0udio. \u00c9s un client de <strong>JACK<\/strong> (el servidor d&#8217;audio de Linux), i est\u00e0 basat com a punt de partida en <em>sndfile-jackplay<\/em> que es troba dins les utilitats de la llibreria <strong>libsndfile<\/strong> (http:\/\/www.mega-nerd.com\/libsndfile\/tools\/#jackplay).<\/p>\n<p>Per tothom \u00e9s sabut que quan es reprodueix un fitxer d&#8217;\u00e0udio al doble de la freq\u00fc\u00e8ncia dura la meitat de temps. Seria equivalent a agafar una mostra de cada dues, i reproduir-les a la mateixa freq\u00fc\u00e8ncia de mostreig original.<\/p>\n<p>Ara anem a fer el cas contrari, volem dividir la freq\u00fc\u00e8ncia per dos, i el temps que durar\u00e0 la reproducci\u00f3 hauria de ser el doble. Per fer-ho, el m\u00e9s f\u00e0cil \u00e9s doblar cada mostra en dues, i reproduir-ho a la freq\u00fc\u00e8ncia de mostreig original.<\/p>\n<p>Aquests dos casos especials, multiplicar per dos i dividir per dos, s\u00f3n els casos f\u00e0cils i m\u00e9s evidents. Un an\u00e0lisi d&#8217;aquests casos i estudiar el codi proporcionat pot aclarir molts conceptes per als estudiants del Processament Digital del Senyal. Ara b\u00e9, m\u00e9s dif\u00edcil \u00e9s fer freq\u00fc\u00e8ncies intermitges entre 0.5 i 2; i m\u00e9s dif\u00edcil encara \u00e9s fer un escombrat continu de freq\u00fcencies en un rang determinat. Tot aix\u00f2 \u00e9s el que es pot veure i es pot estudiar en aquesta aplicaci\u00f3 que t\u00e9 un car\u00e0cter did\u00e0ctic.<\/p>\n<p>La sortida de l&#8217;ajuda del programa proporciona la seg\u00fcent informaci\u00f3:<\/p>\n<blockquote><p>\n$ jplay-sndfile -h<\/p>\n<p>jplay-sndfile 1.00<br \/>\nCreated by Joan Quintana Compte (joanillo)<br \/>\njoanqc arroba gmail.com &#8211; www.joanillo.org<br \/>\nLicensed under GPL v.3<\/p>\n<p>jplay-sndfile is a JACK client intended for playing audio files (wav) and pitch shifting, written basically for learning, testing and educational purposes, and the first stage for future developments. A part of playing an audio file, you can change the pitch (between *0.5 and *2) of your audio file, you can play the audio file combing the pitch between two ranges. For testing is useful a sine wave, but remember that you can use any mono (one channel) audio files.<br \/>\nThis Jack Audio client connects automatically to system:playback_1 and system:playback_2<\/p>\n<p>usage: jplay-sndfile [-h] [[pitch-shift] | [pitch-shift-start pitch-shift-end]]  wav-file<\/p>\n<p>\\t-h &#8211;help: this usage information<br \/>\n\\t[pitch-shift] (0.5,2): shifting pitch<br \/>\n\\t[pitch-shift-start] (0.5,2): shifting pitch start range<br \/>\n\\t[pitch-shift-end] (0.5,2): shifting pitch end range<br \/>\n\\twav file: mono channel audio file<br \/>\n\\t<\/p>\n<p>\\tExamples:<br \/>\n\\t.\/jplay_sndfile samples\/hellosine.wav<br \/>\n\\t.\/jplay_sndfile 0.65 samples\/hellosine.wav<br \/>\n\\t.\/jplay_sndfile 0.5 2 samples\/hellosine.wav<\/p><\/blockquote>\n<p>La mostra d&#8217;audio que es presenta vol ser un compendi de qu\u00e8 pot fer <strong>jplay-sndfile<\/strong>, i contempla els seg\u00fcents casos:<\/p>\n<ul>\n<li>.\/jplay_sndfile samples\/test_44100.wav<\/li>\n<li>.\/jplay_sndfile .5 samples\/test_44100.wav<\/li>\n<li>.\/jplay_sndfile .8 samples\/test_44100.wav<\/li>\n<li>.\/jplay_sndfile 1.4 samples\/test_44100.wav<\/li>\n<li>.\/jplay_sndfile 2 samples\/test_44100.wav<\/li>\n<li>.\/jplay_sndfile .5 2 samples\/test_44100x3.wav<\/li>\n<li>.\/jplay_sndfile samples\/sine_440_44100.wav<\/li>\n<li>.\/jplay_sndfile .5 1 samples\/square_440_44100.wav<\/li>\n<li>.\/jplay_sndfile 1 2 samples\/saw_440_44100.wav<\/li>\n<li>.\/jplay_sndfile .5 samples\/waves.wav<\/li>\n<li>.\/jplay_sndfile 2 samples\/waves.wav<\/li>\n<\/ul>\n<p><object height=\"81\" width=\"100%\"><param name=\"movie\" value=\"https:\/\/player.soundcloud.com\/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F37445618\"><param name=\"allowscriptaccess\" value=\"always\"><embed allowscriptaccess=\"always\" height=\"81\" src=\"https:\/\/player.soundcloud.com\/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F37445618\" type=\"application\/x-shockwave-flash\" width=\"100%\"><\/object>  <span><a href=\"http:\/\/soundcloud.com\/joanillo\/jplay-sndfile-examples\">jplay-sndfile-examples<\/a> by <a href=\"http:\/\/soundcloud.com\/joanillo\">joanillo<\/a><\/span><\/p>\n<p>Una de les coses m\u00e9s interessants \u00e9s estudiar la funci\u00f3 <strong>callback<\/strong> de la <strong>API<\/strong> de <strong>JACK<\/strong>, que ha quedat bastant petita, i on est\u00e0 tot el moll de l&#8217;os de l&#8217;aplicaci\u00f3. B\u00e0sicament la funci\u00f3 callback() la crida el servidor d&#8217;\u00e0udio cada vegada que la interf\u00edcie d&#8217;\u00e0udio (la targeta de so hardware) necessita omplir el seu buffer amb dades.<\/p>\n<blockquote><p>\nstatic int process (jack_nframes_t nframes, void * arg)<br \/>\n{<\/p>\n<p>\\tjack_default_audio_sample_t buf ;<br \/>\n\\tunsigned int i;<br \/>\n\\touts = (jack_default_audio_sample_t *)jack_port_get_buffer (output_port, nframes) ;<\/p>\n<p>\\tinfo_t *info = (info_t *) arg;<br \/>\n\\t<br \/>\n\\tmemcpy (outs_original, buffer2 + frames_counter_original, sizeof (jack_default_audio_sample_t) * nframes * DOUBLE_SAMPLES * 2);<\/p>\n<p>\\tint k=0;<br \/>\n\\tfloat k2;<br \/>\n\\tk2 = nframes\/info-&gt;shift_pitch;<br \/>\n\\tfloat var, var2 = 0;<br \/>\n\\tint part_entera = 0;<br \/>\n\\tvar = 1\/info-&gt;shift_pitch &#8211; 1;<\/p>\n<p>\\tfor (i = 0 ; i &lt; nframes ; i++)<br \/>\n\\t{\\t<\/p>\n<p>\\t\\tif (info-&gt;shift_pitch &lt; 1) {<br \/>\n\\t\\t\\tif (frames_counter + i &gt;= info-&gt;numFrames \/ shift_pitch_equivalent) { \/\/ shift_pitch_equivalent = info.shift_pitch quan no faig un escombrat<br \/>\n\\t\\t\\tinfo-&gt;play_done=1;<br \/>\n\\t\\t\\treturn 0;<br \/>\n\\t\\t\\t}<br \/>\n\\t\\t} else { \/\/ &gt;= 1<br \/>\n\\t\\t\\tif (frames_counter_original + i &gt;= info-&gt;numFrames * DOUBLE_SAMPLES) {<br \/>\n\\t\\t\\tinfo-&gt;play_done=1;<br \/>\n\\t\\t\\treturn 0;<br \/>\n\\t\\t\\t}<br \/>\n\\t\\t}<br \/>\n\\t\\t<br \/>\n\\t\\tif (info-&gt;shift_pitch &gt; 1) {<br \/>\n\\t\\t\\tk=(int)(i*DOUBLE_SAMPLES*info-&gt;shift_pitch + .5);<br \/>\n\\t\\t\\touts[i] = outs_original[k];\\t<br \/>\n\\t\\t} else if (info-&gt;shift_pitch &lt;= 1) {<br \/>\n\\t\\t\\touts[k] = outs_original[i*DOUBLE_SAMPLES];<br \/>\n\\t\\t\\tif ((int)var2 != part_entera) {<br \/>\n\\t\\t\\t\\touts[k+1] = outs_original[i*DOUBLE_SAMPLES+1];<br \/>\n       \\t\\tpart_entera = int(var2);<br \/>\n       \\t\\tk++;<br \/>\n\\t\\t\\t}<br \/>\n\\t\\t\\tvar2 = var2 + var;<br \/>\n\\t\\t\\tk++;\\t\\t\\t<br \/>\n\\t\\t}<\/p>\n<p>\\t}<br \/>\n\\tframes_counter += nframes;<br \/>\n\\tframes_counter_original += nframes * DOUBLE_SAMPLES * info-&gt;shift_pitch ;<br \/>\n\\t<br \/>\n\\treturn 0 ;<br \/>\n} \/* process *\/<\/p><\/blockquote>\n<p>I per a qu\u00e8 serveix tot aix\u00f2? \u00c9s una aplicaci\u00f3 did\u00e0ctica, serveix sobretot per aprendre:<\/p>\n<ul>\n<li>per aprendre: teoria del Processamet del Senyal<\/li>\n<li>per aprendre: API de libsndfile<\/li>\n<li>per aprendre: API de JACK, exemple de com funciona la funci\u00f3 de callback<\/li>\n<\/ul>\n<p>per\u00f2 a part d&#8217;aprendre, s&#8217;ha desenvolupat amb una idea en ment, que ha de ser el seg\u00fcent projecte: utilitzar una tauleta gr\u00e0fica Wacom, les que fan servir els dissenyadors gr\u00e0fics, per produir sons real\u00edstics, sensibles al moviment i a la pressi\u00f3 del llapis, per\u00f2 aix\u00f2 ser\u00e0 el seg\u00fcent projecte: <a href=\"http:\/\/wiki.joanillo.org\/index.php\/Reconeixement_real_de_gestos_amb_la_wacom_i_s%C3%ADntesi_d%27%C3%A0udio\">Reconeixement real de gestos amb la wacom i S\u00edntesi d&#8217;\u00e0udio<\/a><\/p>\n<ul>\n<li>Descarregar <a href=\"http:\/\/wiki.joanillo.org\/index.php\/Fitxer:Jplay-sndfile-1.0.0.tar.gz\"><strong>jplay-sndfile<\/strong><\/a><\/li>\n<li>enlla\u00e7 del projecte a la <a href=\"http:\/\/wiki.joanillo.org\/index.php\/Jplay-sndfile\"><strong>wiki<\/strong><\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>jplay-sndfile \u00e9s una aplicaci\u00f3 que he estat programant la \u00faltima setmana i que t\u00e9 un car\u00e0cter did\u00e0ctic. B\u00e0sicament \u00e9s un reproductor de fitxers d&#8217;\u00e0udio, que a m\u00e9s pot aplicar un canvi de freq\u00fc\u00e8ncia, i tamb\u00e9 pot fer un escombrat continu de freq\u00fc\u00e8ncies sobre la mostra d&#8217;\u00e0udio. \u00c9s un client de JACK (el servidor d&#8217;audio de [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[15,18,16,12,5],"tags":[],"_links":{"self":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/166"}],"collection":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=166"}],"version-history":[{"count":1,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":167,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions\/167"}],"wp:attachment":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}