{"id":2984,"date":"2012-08-16T16:42:00","date_gmt":"2012-08-16T23:42:00","guid":{"rendered":"https:\/\/pkmital.com\/home\/?post_type=pkm_teaching&#038;p=2984"},"modified":"2023-08-22T17:59:42","modified_gmt":"2023-08-23T00:59:42","slug":"audiovisual-processing-for-ios-devices","status":"publish","type":"pkm_teaching","link":"https:\/\/pkmital.com\/home\/teaching\/audiovisual-processing-for-ios-devices\/","title":{"rendered":"V&#038;A Museum | Audiovisual Processing for iOS Devices"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Introduction<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the homepage for the V&amp;A course on Developing Audiovisual Apps for the iPhone\/iPad using openFrameworks. This site will hold code samples and additional resources for development.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Please make sure you already have a coding environment setup to use openFrameworks v007:&nbsp;<a href=\"http:\/\/openframeworks.cc\/download\" target=\"_blank\" rel=\"noreferrer noopener\">openFrameworks<\/a>. You will want to get the OSX version to begin with, and when we start developing on the iPhone\/iPad, we will want to use the iOS download.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">C++ Resources &amp; Books<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a rel=\"noreferrer noopener\" href=\"http:\/\/www.cplusplus.com\/doc\/tutorial\/\" target=\"_blank\">C++ Tutorial<\/a><br><a rel=\"noreferrer noopener\" href=\"http:\/\/www.cprogramming.com\/tutorial\/\" target=\"_blank\">Another C++ Tutorial<\/a><br><a rel=\"noreferrer noopener\" href=\"http:\/\/books.google.co.uk\/books?id=tTFhAAAACAAJ&amp;dq=Bjarne+Stroustrup&amp;hl=en&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;redir_esc=y\" target=\"_blank\">Bjarne Stroustrup\u2019s The C++ Programming Language<\/a><br><a rel=\"noreferrer noopener\" href=\"http:\/\/books.google.co.uk\/books?id=4UrFQFZWmqsC&amp;dq=Bjarne+Stroustrup&amp;source=gbs_book_similarbooks\" target=\"_blank\">Deitel &amp; Deitel\u2019s C++ How to Program<\/a><br><a rel=\"noreferrer noopener\" href=\"http:\/\/www.openframeworks.cc\/documentation\/\" target=\"_blank\">openFrameworks Documentation<\/a><br><a rel=\"noreferrer noopener\" href=\"http:\/\/forum.openframeworks.cc\/\" target=\"_blank\">openFrameworks Forum<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you are having trouble compiling the OSX-based openFrameworks examples (not the iOS examples), make sure your project settings are set to use the 10.6 SDK and use a build architecture of 32-bit. The following image shows you how to change both the project and target settings of both your openFrameworks and emptyExample project.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"370\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/6876558695_c99dfcd3ae_o-1.png\" alt=\"\" class=\"wp-image-2987\" srcset=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/6876558695_c99dfcd3ae_o-1.png 860w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/6876558695_c99dfcd3ae_o-1-800x344.png 800w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/6876558695_c99dfcd3ae_o-1-768x330.png 768w\" sizes=\"auto, (max-width: 860px) 100vw, 860px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In order to change your application\u2019s name, you will need to navigate to your Target\u2019s Build Settings. The picture below is meant to help you find the \u201cProduct Name\u201d setting. Click on your XCode project, then Target, then Build Setting Tab. Search for \u201cProduct Name\u201d, and you can change the value here.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1173\" height=\"158\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-1.11.27-PM-1.png\" alt=\"\" class=\"wp-image-2988\" srcset=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-1.11.27-PM-1.png 1173w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-1.11.27-PM-1-800x108.png 800w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-1.11.27-PM-1-768x103.png 768w\" sizes=\"auto, (max-width: 1173px) 100vw, 1173px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Also, when you need screenshots for your App to publish on the App Store, you can use your iPhone\/iPad to take screenshots. Hold the Home and Lock buttons for about 1.5 seconds, and you will see the screen flash white. If so, you will find a screenshot in your Photo Library on your device.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Week 1: iPhone, App Store, XCode, openFrameworks<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">This week, we were introduced to some of the capabilities in the iPhone and iPad hardware, and also saw some successful apps in the App Store. We then had a gentle introduction to XCode and openFrameworks, creating our first program which displayed a camera and video image. We learned about creating a new project by copying the emptyExample folder to our own folder maintaining the same directory hierarchy. Also, we saw the the \u201cdata\u201d folder inside our \u201cbin\u201d folder is a convenient location to store things like movies, sounds, and images that are relevant to our application.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Lecture Slides<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<div data-wp-interactive=\"core\/file\" class=\"wp-block-file\"><object data-wp-bind--hidden=\"!state.hasPdfPreview\" hidden class=\"wp-block-file__embed\" data=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/ACFrOgCJ0zYSzwOdaPsUcb5TEgqk1lKcpRbg4MZEp-_WZVAKqg0_SQSDlPEi2IX8a4MZcacCfK3bp8F1CqMDlhBzJuipE8Z7wmwxjqpv6Mrje6JL22S1Sr0Ldef91sspx6YSpcrCAMD0zLr_7T_-.pdf\" type=\"application\/pdf\" style=\"width:100%;height:600px\" aria-label=\"Embed of ACFrOgCJ0zYSzwOdaPsUcb5TEgqk1lKcpRbg4MZEp-_WZVAKqg0_SQSDlPEi2IX8a4MZcacCfK3bp8F1CqMDlhBzJuipE8Z7wmwxjqpv6Mrje6JL22S1Sr0Ldef91sspx6YSpcrCAMD0zLr_7T_-.\"><\/object><a id=\"wp-block-file--media-582c983b-ac6b-4430-8a81-2ff21539470b\" href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/ACFrOgCJ0zYSzwOdaPsUcb5TEgqk1lKcpRbg4MZEp-_WZVAKqg0_SQSDlPEi2IX8a4MZcacCfK3bp8F1CqMDlhBzJuipE8Z7wmwxjqpv6Mrje6JL22S1Sr0Ldef91sspx6YSpcrCAMD0zLr_7T_-.pdf\">ACFrOgCJ0zYSzwOdaPsUcb5TEgqk1lKcpRbg4MZEp-_WZVAKqg0_SQSDlPEi2IX8a4MZcacCfK3bp8F1CqMDlhBzJuipE8Z7wmwxjqpv6Mrje6JL22S1Sr0Ldef91sspx6YSpcrCAMD0zLr_7T_-<\/a><a href=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/ACFrOgCJ0zYSzwOdaPsUcb5TEgqk1lKcpRbg4MZEp-_WZVAKqg0_SQSDlPEi2IX8a4MZcacCfK3bp8F1CqMDlhBzJuipE8Z7wmwxjqpv6Mrje6JL22S1Sr0Ldef91sspx6YSpcrCAMD0zLr_7T_-.pdf\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-582c983b-ac6b-4430-8a81-2ff21539470b\">Download<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 2: Classes, Vectors, and Buttons<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Week 2 saw a lot more coding as we jumped into developing an interactive application that would draw multiple buttons. We will eventually use these buttons for the control of sound, being able to record and play back sound samples with the press of our touchscreen. We learned about defining our own classes by creating a \u201c.h\u201d and \u201c.cpp\u201d file. By the end of the class, we were just introduced to vectors, but will have more time to expand on these concepts in the next class in 2 weeks time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Be sure to place these images in your \u201cdata\u201d folder:&nbsp;<a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2012\/01\/button-images.zip\">button-images.zip<\/a>. Here is also a zip file of the code reproduced below:&nbsp;<a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2012\/01\/week2.zip\">week2.zip<\/a>. Your homework is to study \u201c<a href=\"http:\/\/www.cprogramming.com\/tutorial\/c\/lesson3.html\" target=\"_blank\" rel=\"noreferrer noopener\">for loops<\/a>\u201c, \u201c<a href=\"http:\/\/www.cprogramming.com\/tutorial\/lesson8.html\" target=\"_blank\" rel=\"noreferrer noopener\">arrays<\/a>\u201c, and \u201c<a href=\"http:\/\/www.cprogramming.com\/tutorial\/stl\/vector.html\" target=\"_blank\" rel=\"noreferrer noopener\">vectors<\/a>\u201c, in order to reduce the code in the testApp.cpp file. If you are feeling more ambitious, try and make each button do something, such as play a sound (hint:&nbsp;<a href=\"http:\/\/www.openframeworks.cc\/documentation\/sound\/ofSoundPlayer.html\" target=\"_blank\" rel=\"noreferrer noopener\">ofSoundPlayer<\/a>, and also be sure to check the openFrameworks examples on audio input and output!). We\u2019ll look at how to do these together in 2 weeks time, as well as play with audio input and use a lot more for loops.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Button Pads<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;padButton.h&quot;\n \n\/\/ these are macros, which we treat as constant variables\n#define WIDTH 480\n#define HEIGHT 320\n \nclass testApp : public ofBaseApp{\n \n    public:\n     \n    \/\/ initialization\n        void setup();\n     \n    \/\/ main loop of update\/draw\/update\/draw\/update\/draw...\n        void update();\n        void draw();\n \n    \/\/ mouse\/keyboard callbacks\n        void keyPressed  (int key);\n        void keyReleased(int key);\n        void mouseMoved(int x, int y );\n        void mouseDragged(int x, int y, int button);\n        void mousePressed(int x, int y, int button);\n        void mouseReleased(int x, int y, int button);\n     \n    \/\/ window callbacks\n        void windowResized(int w, int h);\n        void dragEvent(ofDragInfo dragInfo);\n        void gotMessage(ofMessage msg);\n     \n     \n    \/\/ for scaling our app for iphone\/ipad\n    float scaleX, scaleY;\n     \n    \/\/ single instance of our padButton class\n    \/\/ padButton button1;\n     \n    \/\/ a vector is a c-standard library implementation of an array\n    \/\/ this allows us to create multiple buttons\n    vector&amp;lt;padButton&gt; buttons;\n \n \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n    ofSetWindowShape(WIDTH, HEIGHT);\n     \n    scaleX = WIDTH \/ 1024.0;\n    scaleY = HEIGHT \/ 768.0;\n     \n    \/\/ we allow our vector to have 4 padButtons, which we index from 0 - 3\n    buttons.resize(4);\n     \n    \/\/ the first index, we setup our button by calling the following methods\n    buttons&#x5B;0].setPosition(0, 0);\n    buttons&#x5B;0].setSize(200, 200);\n    buttons&#x5B;0].loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n     \n    \/\/ and so on... \n    buttons&#x5B;1].setPosition(200, 0);\n    buttons&#x5B;1].setSize(200, 200);\n    buttons&#x5B;1].loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n     \n    buttons&#x5B;2].setPosition(400, 0);\n    buttons&#x5B;2].setSize(200, 200);\n    buttons&#x5B;2].loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n     \n    buttons&#x5B;3].setPosition(600, 0);\n    buttons&#x5B;3].setSize(200, 200);\n    buttons&#x5B;3].loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n     \n     \n    \/*\n    button1.setPosition(0, 0);\n    button1.setSize(200, 200);\n    button1.loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n    *\/\n     \n    \/\/buttons.push_back(button1);\n     \n    \/*\n    button_image_up.loadImage(&quot;button.png&quot;);\n    button_image_down.loadImage(&quot;button-down.png&quot;);\n    button_x = 0;\n    button_y = 0;\n    button_width = 200;\n    button_height = 200;\n    button_state = NORMAL;\n    *\/\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    \/\/ for scaling our whole canvas\n    ofScale(scaleX, scaleY);\n     \n    \/\/ let&#039;s draw all of our buttons \n    buttons&#x5B;0].draw();\n    buttons&#x5B;1].draw();\n    buttons&#x5B;2].draw();\n    buttons&#x5B;3].draw();\n     \n    \/\/button1.draw();\n     \n    \/*\n    \/\/ allow alpha transparency\n    ofEnableAlphaBlending();\n     \n    if(button_state == NORMAL)\n    {\n        button_image_up.draw(button_x, \n                             button_y, \n                             button_width, \n                             button_height);\n    }\n    else\n    {\n        button_image_down.draw(button_x, \n                               button_y);\n    }\n     \n    \/\/ ok done w\/ alpha blending\n    ofDisableAlphaBlending();\n    *\/\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::keyPressed(int key){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::keyReleased(int key){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseMoved(int x, int y ){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseDragged(int x, int y, int button){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mousePressed(int x, int y, int button){\n    \/*\n    if( x &gt; button_x &amp;amp;&amp;amp; y &gt; button_y \n       &amp;amp;&amp;amp; x &amp;lt; (button_x + button_width) \n       &amp;amp;&amp;amp; y &amp;lt; (button_y + button_height) )\n       {\n           button_state = BUTTON_DOWN;\n       }\n     *\/\n     \n    \/\/ and interaction callbacks, which we must scale for different devices\n    buttons&#x5B;0].pressed(x \/ scaleX, y \/ scaleY);\n    buttons&#x5B;1].pressed(x \/ scaleX, y \/ scaleY);\n    buttons&#x5B;2].pressed(x \/ scaleX, y \/ scaleY);\n    buttons&#x5B;3].pressed(x \/ scaleX, y \/ scaleY);\n    \/\/button1.pressed(x \/ scaleX, y \/ scaleY);\n} \n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseReleased(int x, int y, int button){\n\/*    \n    button_state = NORMAL;\n *\/\n    \/\/ and interaction callbacks, which we must scale for different devices\n    buttons&#x5B;0].released(x \/ scaleX, y \/ scaleY);\n    buttons&#x5B;1].released(x \/ scaleX, y \/ scaleY);\n    buttons&#x5B;2].released(x \/ scaleX, y \/ scaleY);\n    buttons&#x5B;3].released(x \/ scaleX, y \/ scaleY);\n    \/\/button1.released(x \/ scaleX, y \/ scaleY);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::windowResized(int w, int h){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMessage(ofMessage msg){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::dragEvent(ofDragInfo dragInfo){ \n \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>padButton.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n\/\/ include file only once\n#pragma once\n \n\/\/ include openframeworks\n#include &quot;ofMain.h&quot;\n \n\/\/ declare the padbutton class and methods\nclass padButton {\npublic:\n     \n    \/\/ enumerators allow us to assign more interesting names to values of an integer\n    \/\/ we could use an integer to the same effect, \n    \/\/ e.g. &quot;int button_state = 0&quot;, when our button is down\n    \/\/ and &quot;int button_state = 1&quot;, when our button is normal,\n    \/\/ but enumerators allow us to instead say\n    \/\/ &quot;BUTTON_STATE button_state = BUTTON_DOWN&quot;, when our button is down,\n    \/\/ &quot;BUTTON_STATE button_state = NORMAL&quot;, when our button is normal.\n    enum BUTTON_STATE {\n        BUTTON_DOWN,\n        NORMAL\n    };\n     \n    \/\/ default constructor - no parameters, no return type\n    padButton();\n     \n    \/\/ methods which our button class will define\n    \/\/ one for loading images for each of the button states\n    void loadImages(string state_normal, string state_down);\n     \n    \/\/ setters, to set internal variables\n    \/\/ the position\n    void setPosition(int x, int y);\n    \/\/ the size\n    void setSize(int w, int h);\n     \n    \/\/ drawing the buttons\n    void draw();\n     \n    \/\/ and interaction with the button\n    void pressed(int x, int y);\n    void released(int x, int y);\n     \nprivate:\n     \n    \/\/ images for drawing\n    ofImage button_image_normal, button_image_down;\n     \n    \/\/ our position\n    int button_x, button_y;\n     \n    \/\/ size\n    int button_width, button_height;\n     \n    \/\/ and internal state of the button\n    BUTTON_STATE button_state;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>padButton.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &amp;lt;iostream&gt;\n#include &quot;padButton.h&quot;\n \n\/\/ default constructor definition\npadButton::padButton()\n{\n    \/\/ by default, we have a very boring button\n    button_x = 0;\n    button_y = 0;\n    button_width = 0;\n    button_height = 0;\n    button_state = NORMAL;\n}\n \nvoid padButton::loadImages(string state_normal, string state_down)\n{\n    \/\/ load the images for our buttons\n    button_image_normal.loadImage(state_normal);\n    button_image_down.loadImage(state_down);\n}\nvoid padButton::setPosition(int x, int y)\n{\n    \/\/ set our internal variables\n    button_x = x;\n    button_y = y;\n}\nvoid padButton::setSize(int w, int h)\n{\n    \/\/ set our internal variables\n    button_width = w;\n    button_height = h;\n}\n \nvoid padButton::draw()\n{\n    \/\/ allow alpha transparency\n    ofEnableAlphaBlending();\n     \n    \/\/ if our button is normal\n    if(button_state == NORMAL)\n    {\n        \/\/ draw the normal button image\n        button_image_normal.draw(button_x, \n                                 button_y, \n                                 button_width, \n                                 button_height);\n    }\n    else\n    {\n        \/\/ draw the down image\n        button_image_down.draw(button_x, \n                               button_y);\n    }\n     \n    \/\/ ok done w\/ alpha blending\n    ofDisableAlphaBlending();\n}\n \nvoid padButton::pressed(int x, int y)\n{\n    \/\/ compound boolean expressions to determine,\n    \/\/ is our x,y input within the bounds of the button\n    \/\/ we have to check the left, the top, the right, and the bottom sides \n    \/\/ of the button, respectively.\n    if( x &gt; button_x &amp;amp;&amp;amp; y &gt; button_y \n       &amp;amp;&amp;amp; x &amp;lt; (button_x + button_width) \n       &amp;amp;&amp;amp; y &amp;lt; (button_y + button_height) )\n    {\n        button_state = BUTTON_DOWN;\n    }\n}\n \nvoid padButton::released(int x, int y)\n{\n    \/\/ ok back to normal\n    button_state = NORMAL;\n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 3: For-loops, iOS, &amp; Multitouch<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"635\" height=\"339\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-17-at-11.37.12-AM.png\" alt=\"\" class=\"wp-image-2991\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This week we explored the use of for-loops for minimizing our button code, and tried drawing a a single row of buttons comprised of many columns. We then explored nested-for loops and tried drawing many rows of buttons, still comprised of many columns. The result was a square matrix of buttons. Our next step was to explore multi-touch functionality which meant finally moving our code to compile on an iOS device. To those students that I was unable to get an iOS account for: the V&amp;A is currently working on getting an account for us. Yet, everyone will still be able to run their code in the iPhone or iPad simulator, an emulator of the iPhone\/iPad!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When developing for iOS devices with openFrameworks, make sure you have downloaded the openFrameworks iOS version here:\u00a0<a rel=\"noreferrer noopener\" href=\"http:\/\/www.openframeworks.cc\/download\" target=\"_blank\">openFrameworks download page<\/a>. Up until now, we were working with the OSX version of openFrameworks. Though the iOS version allows us to write very similar code but compile for an iOS device. Try running the \u201cemptyExample\u201d inside of the iOS openFrameworks download. This is in a folder \u201capps\/iPhoneExamples\/emptyExample\u201d. Now try copying this folder to a new one, maintaining the directory hierarchy as we\u2019ve done in previous applications, and rewrite our padButton code to run on the iPhone simulator. You\u2019ll need to add the padButton.h and padButton.cpp files to your \u201csrc\u201d directory, as well as drag them into XCode, so that your project knows about them. Also, you need to add the \u201cbutton.png\u201d and \u201cbutton-down.png\u201d files to your \u201cdata\u201d folder, and also drag these into your XCode project. This is important since your device will need these files. See the figure below and notice the files I have included in my project. I\u2019ve also copied the code below.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/padbutton.jpg\" alt=\"\" class=\"wp-image-2992\" style=\"width:511px;height:383px\" width=\"511\" height=\"383\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For your homework, please make sure you have this running at least in the Simulator. As well, try exploring other configurations of buttons and the multi-touch functionality.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Button Pads iOS<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n \n#include &quot;padButton.h&quot;\n \n\/\/ these are macros, which we treat as constant variables\n#define WIDTH 480\n#define HEIGHT 320\n \n \nclass testApp : public ofxiPhoneApp {\n     \npublic:\n    void setup();\n    void update();\n    void draw();\n    void exit();\n     \n    void touchDown(ofTouchEventArgs &amp;amp;touch);\n    void touchMoved(ofTouchEventArgs &amp;amp;touch);\n    void touchUp(ofTouchEventArgs &amp;amp;touch);\n    void touchDoubleTap(ofTouchEventArgs &amp;amp;touch);\n    void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n \n    void lostFocus();\n    void gotFocus();\n    void gotMemoryWarning();\n    void deviceOrientationChanged(int newOrientation);\n     \n    \/\/ for scaling our app for iphone\/ipad\n    float scaleX, scaleY;\n     \n    \/\/ single instance of our padButton class\n    \/\/ padButton button1;\n     \n    \/\/ a vector is a c-standard library implementation of an array\n    \/\/ this allows us to create multiple buttons\n    vector&amp;lt;padButton&gt; buttons;\n    int numButtons;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){  \n    \/\/ register touch events\n    ofRegisterTouchEvents(this);\n     \n    \/\/ initialize the accelerometer\n    ofxAccelerometer.setup();\n     \n    \/\/iPhoneAlerts will be sent to this.\n    ofxiPhoneAlerts.addListener(this);\n     \n    \/\/If you want a landscape oreintation \n    \/\/iPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);\n     \n     \n     \n    ofSetWindowShape(WIDTH, HEIGHT);\n     \n    scaleX = WIDTH \/ 1024.0;\n    scaleY = HEIGHT \/ 768.0;\n     \n     \n    numButtons = 5;\n     \n    \/\/ we allow our vector to have 4 padButtons, which we index from 0 - 3\n    buttons.resize(numButtons * numButtons);\n     \n    \/\/ use a nested loop to initialize our buttons, setting their positions as a square matrix\n    \/\/ - this outer-loop iterates over ROWS\n    for (int j = 0; j &amp;lt; numButtons; j++)\n    {\n        \/\/ - this inner-loop iterates over COLUMNS\n        for (int i = 0; i &amp;lt; numButtons; i = i + 1) \n        {\n            \/\/ notice how we use the loop variables, i and j, in setting the x,y positions of each button\n            buttons&#x5B;j * numButtons + i].setPosition(200 * i, 200 * j);\n            buttons&#x5B;j * numButtons + i].setSize(200, 200);\n            buttons&#x5B;j * numButtons + i].loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n        }\n    }\n     \n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    \/\/ for scaling our whole canvas\n    ofScale(scaleX, scaleY);\n     \n    \/\/ let&#039;s draw all of our buttons \n    for (int i = 0; i &amp;lt; numButtons * numButtons; i++) {\n        buttons&#x5B;i].draw();\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::exit(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp;touch){\n    \/\/ and interaction callbacks, which we must scale for different devices\n    for (int i = 0; i &amp;lt; numButtons * numButtons; i++) {\n        buttons&#x5B;i].pressed(touch.x \/ scaleX, touch.y \/ scaleY);\n    }\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp;touch){\n    \/\/ and interaction callbacks, which we must scale for different devices\n    for (int i = 0; i &amp;lt; numButtons * numButtons; i++) {\n        buttons&#x5B;i].released(touch.x \/ scaleX, touch.y \/ scaleX);\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::lostFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMemoryWarning(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::deviceOrientationChanged(int newOrientation){\n \n}\n \n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs&amp;amp; args){\n \n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Week 4: Recording, Playing, and Drawing Audio<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">This week we explored how to get our application to have access to the microphone and speaker. We first drew samples from the microphone, then created a feedback-loop where the microphone samples were sent to the speaker, and finally learned how to record a chunk of audio using our previous button class as a \u201crecord\u201d and \u201cplay\u201d button. The code is copied below and requires the \u201ciOS\u201d version of openFrameworks. So working with the \u201cemptyExample\u201d of the iOS version (\/of_preRelease_v007_iphone\/apps\/iPhoneExamples\/emptyExample), try playing with the code below. Please have a read through the code and get it compiled on your own machine in your own time. Feel free to shoot me an e-mail if you have any questions. As a lot was covered, your homework is to explore the code in more depth and to understand it as much as possible.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Microphone Input<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n \nclass testApp : public ofxiPhoneApp{\n     \npublic:\n    void setup();\n    void update();\n    void draw();\n     \n    \/\/ touch callbacks\n    void touchDown(ofTouchEventArgs &amp;amp;touch);\n    void touchMoved(ofTouchEventArgs &amp;amp;touch);\n    void touchUp(ofTouchEventArgs &amp;amp;touch);\n    void touchDoubleTap(ofTouchEventArgs &amp;amp;touch);\n    void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n     \n     \n    \/\/ new method for getting the samples from the microphone\n    void audioIn( float * input, int bufferSize, int nChannels );\n \n    int     width, height;\n     \n    \/\/ variables which will help us deal with audio\n    int     initialBufferSize;\n    int     sampleRate;\n    float   * buffer;\n     \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n \n    \/\/ register touch events\n    ofRegisterTouchEvents(this);\n    \/\/ change our phone orientation to landscape\n    ofxiPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);\n \n    \/\/ variable for our audio\n    initialBufferSize   = 512;          \/\/ how many samples per &quot;frame&quot;.  each time &quot;audioIn&quot; gets called, we have this many samples\n    sampleRate          = 44100;        \/\/ how many samples per second.  so sampleRate\/initialBufferSize is our audio frame rate, or frames per second.\n     \n    \/\/ we set our buffer pointer to a chunk of memory &quot;initialBufferSize&quot; large.  this is called memory allocation.\n    buffer              = new float&#x5B;initialBufferSize];\n     \n    \/\/ now we set that portion of memory to equal 0, or else it may be filled with garbage\n    memset(buffer, 0, initialBufferSize * sizeof(float));\n \n    \/\/ 0 output channels,\n    \/\/ 1 input channels\n    \/\/ 44100 samples per second\n    \/\/ 512 samples per buffer\n    \/\/ 4 num buffers (latency)\n    ofSoundStreamSetup(0, 1, this, sampleRate, initialBufferSize, 4);\n    ofSetFrameRate(60);\n     \n    \/\/ resize our window\n    width = 480;\n    height = 320;\n    ofSetWindowShape(width, height);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    \/*\n    \/\/ intialize a variable with 1 element only\n    float buffer;\n    buffer = 0;\n     \n     \/\/ initialize an array of 512 elements\n    float buffer&#x5B;512];\n    \/\/ can&#039;t write: buffer = 0;\n    buffer&#x5B;0] = 0;\n    buffer&#x5B;1] = 0; \n    ...\n    ...\n    buffer&#x5B;511] = 0;\n     \n    \/\/ create a pointer which points to memory.  \n    \/\/ by default, this pointer is NULL, as in it doesn&#039;t point to any memory.\n    \/\/ then the right side of the equation allocates 512 elements in memory, \n    \/\/ and sets the pointer on the left side to  &quot;point&quot; to that location in memory.\n    float *buffer = new float&#x5B;512];\n     \n    \/\/ we can &quot;dereference&quot; the pointer using the same notation as the array above\n    buffer&#x5B;0] = 0;  \/\/ equivalent to: *(buffer + 0) = 0;\n    buffer&#x5B;1] = 0; \n    ...\n    ...\n    buffer&#x5B;511] = 0;\n    *\/\n     \n    ofBackground(0);\n     \n    \/\/ let&#039;s move halfway down the screen\n    ofTranslate(0, height\/2);\n     \n    \/\/ ratio of the screen size to the size of my buffer\n    float width_ratio = width \/ (float)initialBufferSize;\n     \n    \/\/ change future drawing commands to be white\n    ofSetColor(255, 255, 255);\n     \n    \/\/ we rescale our drawing to be 100x as big, since our audio waveform is only between &#x5B;-1,1].\n    float amplitude = 100;\n     \n    \/\/ lets draw the entire buffer by drawing tiny line segments from &#x5B;0-1, 1-2, 2-3, 3-4, ... 510-511]\n    for (int i = 1; i &amp;lt; initialBufferSize; i++) {   \/\/ we start at 1 instead of 0\n        ofLine((i-1)*width_ratio,                   \/\/ the first time this will be the x-value of the 0th buffer value\n               buffer&#x5B;i-1]*amplitude,               \/\/ the y-value of the 0th buffer value\n               i*width_ratio,                       \/\/ the x-value of the 1st buffer value\n               buffer&#x5B;i]*amplitude);                \/\/ the y-value of the 1st buffer value\n    }\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioIn(float * input, int bufferSize, int nChannels){\n             \n    \/\/ just makes sure we didn&#039;t set &quot;initialBufferSize&quot; to something our audio card can&#039;t handle.\n    if( initialBufferSize != bufferSize ){\n        ofLog(OF_LOG_ERROR, &quot;your buffer size was set to %i - but the stream needs a buffer size of %i&quot;, initialBufferSize, bufferSize);\n        return;\n    }   \n     \n    \/\/ we copy the samples from the &quot;input&quot; which is our microphone, to a variable \n    \/\/ our entire class knows about, buffer.  this buffer has been allocated to have \n    \/\/ the same amount of memory as each &quot;Frame&quot; or &quot;bufferSize&quot; of audio has.\n    \/\/ so we copy the whole 512 sample chunk into our buffer so we can draw it.\n    for (int i = 0; i &amp;lt; bufferSize; i++){\n        buffer&#x5B;i] = input&#x5B;i];\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp;touch) {} \nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp;touch) {}\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp;touch) {}\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp;touch) {}\nvoid testApp::touchCancelled(ofTouchEventArgs &amp;amp;touch) {}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Recording Sound<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">For this example, we want to record a bit of sound using our button class to help us. We need to copy the button classes files (padButton.h\/padButton.cpp) to our project, and also remember to add the images (button.png\/button-down.png) to our data folder. We also modified our button class so that the \u201cpressed\u201d and \u201creleased\u201d functions return a boolean value. This code is copied below.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>test.App.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n#include &quot;padButton.h&quot;\n \nclass testApp : public ofxiPhoneApp{\n     \npublic:\n    void setup();\n    void update();\n    void draw();\n     \n    void touchDown(ofTouchEventArgs &amp;amp;touch);\n    void touchMoved(ofTouchEventArgs &amp;amp;touch);\n    void touchUp(ofTouchEventArgs &amp;amp;touch);\n    void touchDoubleTap(ofTouchEventArgs &amp;amp;touch);\n    void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n \n    void audioIn( float * input, int bufferSize, int nChannels );\n    void audioOut( float * output, int bufferSize, int nChannels );\n     \n    \/\/ our screen size\n    int                 width, height;\n     \n    \/\/ variable for audio\n    int                 initialBufferSize;\n    int                 sampleRate;\n     \n    \/\/ this vector will store our audio recording\n    vector&amp;lt;float&gt;       buffer;\n \n    \/\/ frame will tell us &quot;what chunk of audio are we currently playing back&quot;.\n    \/\/ as we record and play back in &quot;chunks&quot; also called &quot;frames&quot;, we will need \n    \/\/ to keep track of which frame we are playing during playback\n    int                 frame;\n     \n    \/\/ frame will run until it hits the final recorded frame, which is numFrames \n    \/\/ we increment this value every time we record a new frame of audio\n    int                 numFrames;\n     \n    \/\/ our buttons for user interaction\n    padButton           button_play, button_record;\n     \n    \/\/ determined based on whether the user has pressed the play or record buttons\n    bool                bRecording, bPlaying;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n    \/\/ register touch events\n    ofRegisterTouchEvents(this);\n     \n    ofxiPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);\n \n    \/\/for some reason on the iphone simulator 256 doesn&#039;t work - it comes in as 512!\n    \/\/so we do 512 - otherwise we crash\n    initialBufferSize   = 512;\n    sampleRate          = 44100;\n     \n    \/\/buffer                = new float&#x5B;initialBufferSize];\n    \/\/memset(buffer, 0, initialBufferSize * sizeof(float));\n \n    \/\/ 1 output channels, &amp;lt;-- different from the previous example, as now we want to playback\n    \/\/ 1 input channels\n    \/\/ 44100 samples per second\n    \/\/ 512 samples per buffer\n    \/\/ 4 num buffers (latency)\n    ofSoundStreamSetup(1, 1, this, sampleRate, initialBufferSize, 4);\n    ofSetFrameRate(60);\n     \n    \/\/ we initialize our two buttons to act as a play and a record button. \n    button_record.loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n    button_play.loadImages(&quot;button.png&quot;, &quot;button-down.png&quot;);\n    button_record.setPosition(100, 100);\n    button_record.setSize(100, 100);\n    button_play.setPosition(250, 100);\n    button_play.setSize(100, 100);    \n     \n    \/\/ initially not recording\n    bRecording = false;\n    bPlaying = false;\n     \n    \/\/ which audio frame am i currently playing back\n    frame = 0;\n     \n    \/\/ how many audio frames did we record?\n    numFrames = 0;\n     \n    width = 480;\n    height = 320;\n    ofSetWindowShape(width, height);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    ofBackground(0);\n     \n    \/\/ draw our buttons\n    button_record.draw();\n    button_play.draw();\n     \n    ofTranslate(0, height\/2);\n     \n    \/\/ let&#039;s output a string on the screen that helps us determine what the state of the program is\n    if (bPlaying) {\n        ofDrawBitmapString(&quot;Playing: True&quot;, 20,20);\n    }\n    else {\n        ofDrawBitmapString(&quot;Playing: False&quot;, 20,20);\n    }\n     \n    if (bRecording) {\n        ofDrawBitmapString(&quot;Recording: True&quot;, 20,40);\n    }\n    else {\n        ofDrawBitmapString(&quot;Recording: False&quot;, 20,40);\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioOut(float * output, int bufferSize, int nChannels){\n     \n    \/\/ if we are playing back audio (if the user is pressing the play button)\n    if(bPlaying)\n    {\n        \/\/ we set the output to be our recorded buffer\n        for (int i = 0; i &amp;lt; bufferSize; i++){\n            \/\/ so we have to access the current &quot;playback frame&quot; which is a variable \n            \/\/ &quot;frame&quot;.  this variable helps us determine which frame we should play back.\n            \/\/ because one frame is only 512 samples, or 1\/90th of a second of audio, we would like\n            \/\/ to hear more than just that one frame.  so we playback not just the first frame,\n            \/\/ but every frame after that... after 90 frames of audio, we will have heard \n            \/\/ 1 second of the recording... \n            output&#x5B;i] = buffer&#x5B;i + frame*bufferSize];\n        }\n         \n        \/\/ we have to increase our frame counter in order to hear farther into the audio recording\n        frame = (frame + 1) % numFrames;\n    }\n    \/\/ else don&#039;t output anything to the speaker\n    else {\n        memset(output, 0, nChannels * bufferSize * sizeof(float));\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioIn(float * input, int bufferSize, int nChannels){\n             \n    if( initialBufferSize != bufferSize ){\n        ofLog(OF_LOG_ERROR, &quot;your buffer size was set to %i - but the stream needs a buffer size of %i&quot;, initialBufferSize, bufferSize);\n        return;\n    }   \n     \n    \/\/ if we are recording\n    if(bRecording)\n    {\n        \/\/ let&#039;s add the current frame of audio input to our recording buffer.  this is 512 samples.\n        \/\/ (note: another way to do this is to copy the whole chunk of memory using memcpy)\n        for (int i = 0; i &amp;lt; bufferSize; i++)\n        {   \n            \/\/ we will add a sample at a time to the back of the buffer, increasing the size of &quot;buffer&quot;\n            buffer.push_back(input&#x5B;i]);\n        }\n         \n        \/\/ we also need to keep track of how many audio &quot;frames&quot; we have.  this is how many times \n        \/\/ we have recorded a chunk of 512 samples.  we refer to that chunk of 512 samples as 1 frame.\n        numFrames++;\n    }\n    \/\/ otherwise we set the input to 0\n    else \n    {\n        \/\/ set the chunk in memory pointed to by &quot;input&quot; to 0.  the\n        \/\/ size of the chunk is the 3rd argument.\n        memset(input, 0, nChannels * bufferSize * sizeof(float));\n    }\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp;touch){\n    \/\/bRecording = !bRecording;\n     \n    \/\/ NOTE: we have modified our button class to return true or false when the button was pressed\n    \/\/ we set playing or recording to be true depending on whether the user pressed that button\n    bPlaying = button_play.pressed(touch.x, touch.y);\n    bRecording = button_record.pressed(touch.x, touch.y);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp;touch){\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp;touch){\n     \n    \/\/ we then user stops pressing the button, we are no longer playing or recording\n    bPlaying = !button_play.released(touch.x, touch.y);\n    bRecording = !button_record.released(touch.x, touch.y);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs&amp;amp; args){\n \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>padButton.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n\/\/ include file only once\n#pragma once\n \n\/\/ include openframeworks\n#include &quot;ofMain.h&quot;\n \n\/\/ declare the padbutton class and methods\nclass padButton {\npublic:\n     \n    \/\/ enumerators allow us to assign more interesting names to values of an integer\n    \/\/ we could use an integer to the same effect, \n    \/\/ e.g. &quot;int button_state = 0&quot;, when our button is down\n    \/\/ and &quot;int button_state = 1&quot;, when our button is normal,\n    \/\/ but enumerators allow us to instead say\n    \/\/ &quot;BUTTON_STATE button_state = BUTTON_DOWN&quot;, when our button is down,\n    \/\/ &quot;BUTTON_STATE button_state = NORMAL&quot;, when our button is normal.\n    enum BUTTON_STATE {\n        BUTTON_DOWN,\n        NORMAL\n    };\n     \n    \/\/ default constructor - no parameters, no return type\n    padButton();\n     \n    \/\/ methods which our button class will define\n    \/\/ one for loading images for each of the button states\n    void loadImages(string state_normal, string state_down);\n     \n    \/\/ setters, to set internal variables\n    \/\/ the position\n    void setPosition(int x, int y);\n    \/\/ the size\n    void setSize(int w, int h);\n     \n    \/\/ drawing the buttons\n    void draw();\n     \n    \/\/ and interaction with the button\n    bool pressed(int x, int y);\n    bool released(int x, int y);\n     \nprivate:\n     \n    \/\/ images for drawing\n    ofImage button_image_normal, button_image_down;\n     \n    \/\/ our position\n    int button_x, button_y;\n     \n    \/\/ size\n    int button_width, button_height;\n     \n    \/\/ and internal state of the button\n    BUTTON_STATE button_state;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>padButton.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &amp;lt;iostream&gt;\n#include &quot;padButton.h&quot;\n \n\/\/ default constructor definition\npadButton::padButton()\n{\n    \/\/ by default, we have a very boring button\n    button_x = 0;\n    button_y = 0;\n    button_width = 0;\n    button_height = 0;\n    button_state = NORMAL;\n}\n \nvoid padButton::loadImages(string state_normal, string state_down)\n{\n    \/\/ load the images for our buttons\n    button_image_normal.loadImage(state_normal);\n    button_image_down.loadImage(state_down);\n}\nvoid padButton::setPosition(int x, int y)\n{\n    \/\/ set our internal variables\n    button_x = x;\n    button_y = y;\n}\nvoid padButton::setSize(int w, int h)\n{\n    \/\/ set our internal variables\n    button_width = w;\n    button_height = h;\n}\n \nvoid padButton::draw()\n{\n    \/\/ allow alpha transparency\n    ofEnableAlphaBlending();\n     \n    \/\/ if our button is normal\n    if(button_state == NORMAL)\n    {\n        \/\/ draw the normal button image\n        button_image_normal.draw(button_x, \n                                 button_y, \n                                 button_width, \n                                 button_height);\n    }\n    else\n    {\n        \/\/ draw the down image\n        button_image_down.draw(button_x, \n                               button_y, \n                               button_width, \n                               button_height);\n    }\n     \n    \/\/ ok done w\/ alpha blending\n    ofDisableAlphaBlending();\n}\n \nbool padButton::pressed(int x, int y)\n{\n    \/\/ compound boolean expressions to determine,\n    \/\/ is our x,y input within the bounds of the button\n    \/\/ we have to check the left, the top, the right, and the bottom sides \n    \/\/ of the button, respectively.\n    if( x &gt; button_x &amp;amp;&amp;amp; y &gt; button_y \n       &amp;amp;&amp;amp; x &amp;lt; (button_x + button_width) \n       &amp;amp;&amp;amp; y &amp;lt; (button_y + button_height) )\n    {\n        button_state = BUTTON_DOWN;\n         \n        \/\/ return yes since the user pressed the button\n        return true;\n    }\n    else {\n        \/\/ no the user didn&#039;t press the button\n        return false;\n    }\n}\n \nbool padButton::released(int x, int y)\n{\n    \/\/ ok back to normal\n    button_state = NORMAL;\n     \n    \/\/ we always return true since that is how our buttons work.\n    return true;\n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 5: Building User Interaction<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"620\" height=\"347\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-17-at-11.40.17-AM.png\" alt=\"\" class=\"wp-image-2996\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This week we furthered our audio input\/output example by exploring drawing a recorded buffer. We then saw how to deal with the program flow with our buttons by using \u201cbooleans\u201d. These booleans helped us understand the state of the program and changed the way the program would function. When you have any user interaction, you have to make sure you account for all the possible states the program can get into, as the user will always try everything possible. A common practice is to assume the user \u201cwill always do the wrong thing\u201d and make sure you code for conditions that tell the user, e.g., you should first record something before playing back the recording.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Homework: create a tape-cassette app which rewinds, goes fast forwards, records, plays backs, maybe also plays while fast forwarding or rewinding. Implement buttons for each of these and create your own aesthetic using graphics.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Tape Cassette Player<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">Make sure you continue to use the iPhone branch of the openFrameworks distribution. I\u2019ve also changed the images for the record and play buttons. You can download the new images to put into your \u201cbin\/data\u201d folder here\u00a0<a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2012\/01\/buttons.zip\">[buttons.zip]<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n#include &quot;padButton.h&quot;\n \nclass testApp : public ofxiPhoneApp{\n     \npublic:\n    void setup();\n    void update();\n    void draw();\n     \n    void touchDown(ofTouchEventArgs &amp;amp;touch);\n    void touchMoved(ofTouchEventArgs &amp;amp;touch);\n    void touchUp(ofTouchEventArgs &amp;amp;touch);\n    void touchDoubleTap(ofTouchEventArgs &amp;amp;touch);\n    void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n \n    void audioIn( float * input, int bufferSize, int nChannels );\n    void audioOut( float * output, int bufferSize, int nChannels );\n     \n    \/\/ our screen size\n    int                 width, height;\n     \n    \/\/ variable for audio\n    int                 initialBufferSize;\n    int                 sampleRate;\n     \n    \/\/ this vector will store our audio recording\n    vector&amp;lt;float&gt;       buffer;\n \n    \/\/ frame will tell us &quot;what chunk of audio are we currently playing back&quot;.\n    \/\/ as we record and play back in &quot;chunks&quot; also called &quot;frames&quot;, we will need \n    \/\/ to keep track of which frame we are playing during playback\n    int                 frame;\n     \n    \/\/ frame will run until it hits the final recorded frame, which is numFrames \n    \/\/ we increment this value every time we record a new frame of audio\n    int                 numFrames;\n     \n    \/\/ our buttons for user interaction\n    padButton           button_play, button_record;\n     \n    \/\/ determined based on whether the user has pressed the play or record buttons\n    bool                bRecording, bPlaying, bRecorded, bDoubleTapped;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/*\n *  Created by Parag K. Mital - http:\/\/pkmital.com\n *  Contact: parag@pkmital.com\n *\n *  Copyright 2011 Parag K. Mital. All rights reserved.\n *\n *   Permission is hereby granted, free of charge, to any person\n *   obtaining a copy of this software and associated documentation\n *   files (the &quot;Software&quot;), to deal in the Software without\n *   restriction, including without limitation the rights to use,\n *   copy, modify, merge, publish, distribute, sublicense, and\/or sell\n *   copies of the Software, and to permit persons to whom the\n *   Software is furnished to do so, subject to the following\n *   conditions:\n *\n *   The above copyright notice and this permission notice shall be\n *   included in all copies or substantial portions of the Software.\n *\n *   THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,\n *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n *   OTHER DEALINGS IN THE SOFTWARE.\n *\/\n \n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n    \/\/ register touch events\n    ofRegisterTouchEvents(this);\n     \n    ofxiPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);\n \n    \/\/for some reason on the iphone simulator 256 doesn&#039;t work - it comes in as 512!\n    \/\/so we do 512 - otherwise we crash\n    initialBufferSize   = 512;\n    sampleRate          = 44100;\n     \n    \/\/buffer                = new float&#x5B;initialBufferSize];\n    \/\/memset(buffer, 0, initialBufferSize * sizeof(float));\n \n    \/\/ 1 output channels, &amp;lt;-- different from the previous example, as now we want to playback\n    \/\/ 1 input channels\n    \/\/ 44100 samples per second\n    \/\/ 512 samples per buffer  = 1 frame\n    \/\/ 4 num buffers (latency)\n    ofSoundStreamSetup(1, 1, this, sampleRate, initialBufferSize, 4);\n    ofSetFrameRate(60);\n     \n    \/\/ we initialize our two buttons to act as a play and a record button. \n    button_record.loadImages(&quot;button-record.png&quot;, &quot;button-record-down.png&quot;);\n    button_play.loadImages(&quot;button-play.png&quot;, &quot;button-play-down.png&quot;);\n    button_record.setPosition(100, 110);\n    button_record.setSize(100, 100);\n    button_play.setPosition(250, 110);\n    button_play.setSize(100, 100);    \n     \n    \/\/ initially not recording\n    bRecording = false;\n    bPlaying = false;\n    bRecorded = false;\n    bDoubleTapped = false;\n     \n    \/\/ which audio frame am i currently playing back\n    frame = 0;\n     \n    \/\/ how many audio frames did we record?\n    numFrames = 0;\n     \n    width = 480;\n    height = 320;\n    ofSetWindowShape(width, height);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n     \n    ofBackground(0);\n     \n    \/\/ draw our buttons\n     \n    \/\/ change future drawing commands to be white\n    ofSetColor(255, 255, 255, 200);\n     \n    button_record.draw();\n    button_play.draw();\n     \n    if(bRecorded)\n    {\n        \/\/ move the drawing down halfway\n        ofTranslate(0, height\/2);\n         \n        \/\/ this is going to store how many pixels we multiply our drawing by\n        float amplitude = 100;\n         \n        \/\/ conversion from samples to pixels\n        float width_ratio = width \/ (float)(initialBufferSize*numFrames);\n         \n        \/\/ draw our audio buffer\n        for (int i = 1; i &amp;lt; initialBufferSize*numFrames; i++) \n        {\n            ofLine((i - 1) * width_ratio, \n                   buffer&#x5B;(i-1)] * amplitude, \n                   i * width_ratio, \n                   buffer&#x5B;i] * amplitude);\n        }\n    }\n     \n     \n     \n     \n    \/*\n    if (bRecorded) {\n         \n        ofPushMatrix();\n         \n        \/\/ let&#039;s move halfway down the screen\n        ofTranslate(0, height\/2);\n         \n        \/\/ ratio of the screen size to the size of my buffer\n        float width_ratio = width \/ (float)(numFrames*initialBufferSize);\n         \n        \/\/ change future drawing commands to be white\n        ofSetColor(255, 255, 255);\n         \n        \/\/ we rescale our drawing to be 100x as big, since our audio waveform is only between &#x5B;-1,1].\n        float amplitude = 100;\n         \n        int step = numFrames*initialBufferSize \/ width;\n         \n        \/\/ lets draw the entire buffer by drawing tiny line segments from &#x5B;0-1, 1-2, 2-3, 3-4, ... 510-511]\n        for (int i = step; i &amp;lt; numFrames*initialBufferSize; i+=step) {   \/\/ we start at 1 instead of 0\n            ofLine((i-step)*width_ratio,                   \/\/ the first time this will be the x-value of the 0th buffer value\n                   buffer&#x5B;i-step]*amplitude,               \/\/ the y-value of the 0th buffer value\n                   i*width_ratio,                       \/\/ the x-value of the 1st buffer value\n                   buffer&#x5B;i]*amplitude);                \/\/ the y-value of the 1st buffer value\n        }\n         \n        ofSetColor(255, 20, 20);\n        ofLine(frame*initialBufferSize*width_ratio, -amplitude, frame*initialBufferSize*width_ratio, amplitude);\n         \n        ofPopMatrix();\n    }\n     \n    *\/\n     \n     \n     \n     \n    \/*\n    \/\/ let&#039;s output a string on the screen that helps us determine what the state of the program is\n    if (bPlaying) {\n        ofDrawBitmapString(&quot;Playing: True&quot;, 20,20);\n    }\n    else {\n        ofDrawBitmapString(&quot;Playing: False&quot;, 20,20);\n    }\n     \n    if (bRecording) {\n        ofDrawBitmapString(&quot;Recording: True&quot;, 20,40);\n    }\n    else {\n        ofDrawBitmapString(&quot;Recording: False&quot;, 20,40);\n    }\n    *\/\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioOut(float * output, int bufferSize, int nChannels){\n     \n    \/\/ if we are playing back audio (if the user is pressing the play button)\n    if(bPlaying &amp;amp;&amp;amp; bRecorded)\n    {\n        \/\/ we set the output to be our recorded buffer\n        for (int i = 0; i &amp;lt; bufferSize; i++){\n            \/\/ so we have to access the current &quot;playback frame&quot; which is a variable \n            \/\/ &quot;frame&quot;.  this variable helps us determine which frame we should play back.\n            \/\/ because one frame is only 512 samples, or 1\/90th of a second of audio, we would like\n            \/\/ to hear more than just that one frame.  so we playback not just the first frame,\n            \/\/ but every frame after that... after 90 frames of audio, we will have heard \n            \/\/ 1 second of the recording... \n            output&#x5B;i] = buffer&#x5B;i + frame*bufferSize];\n        }\n         \n        \/\/ we have to increase our frame counter in order to hear farther into the audio recording\n        frame = (frame + 1) % numFrames; \n         \n    }\n    \/\/ else don&#039;t output anything to the speaker\n    else {\n        memset(output, 0, nChannels * bufferSize * sizeof(float));\n    }\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::audioIn(float * input, int bufferSize, int nChannels){\n             \n    if( initialBufferSize != bufferSize ){\n        ofLog(OF_LOG_ERROR, &quot;your buffer size was set to %i - but the stream needs a buffer size of %i&quot;, initialBufferSize, bufferSize);\n        return;\n    }   \n     \n    \/\/ if we are recording\n    if(bRecording)\n    {\n        \/\/ let&#039;s add the current frame of audio input to our recording buffer.  this is 512 samples.\n        \/\/ (note: another way to do this is to copy the whole chunk of memory using memcpy)\n        for (int i = 0; i &amp;lt; bufferSize; i++)\n        {   \n            \/\/ we will add a sample at a time to the back of the buffer, increasing the size of &quot;buffer&quot;\n            buffer.push_back(input&#x5B;i]);\n        }\n         \n        \/\/ we also need to keep track of how many audio &quot;frames&quot; we have.  this is how many times \n        \/\/ we have recorded a chunk of 512 samples.  we refer to that chunk of 512 samples as 1 frame.\n        numFrames++;\n         \n        bRecorded = true;\n    }\n    \/\/ otherwise we set the input to 0\n    else \n    {\n        \/\/ set the chunk in memory pointed to by &quot;input&quot; to 0.  the\n        \/\/ size of the chunk is the 3rd argument.\n        memset(input, 0, nChannels * bufferSize * sizeof(float));\n    }\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp;touch){\n    \/\/bRecording = !bRecording;\n     \n    \/\/ NOTE: we have modified our button class to return true or false when the button was pressed\n    \/\/ we set playing or recording to be true depending on whether the user pressed that button\n    bPlaying = button_play.pressed(touch.x, touch.y);\n    bRecording = button_record.pressed(touch.x, touch.y);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp;touch){\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp;touch){\n     \n    if (!bDoubleTapped) {\n        \/\/ we then user stops pressing the button, we are no longer playing or recording\n        if(button_play.released(touch.x, touch.y))\n            bPlaying = false;\n        if(button_record.released(touch.x, touch.y))\n            bRecording = false;\n    }\n    bDoubleTapped = false;\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp;touch){\n    bPlaying = button_play.pressed(touch.x, touch.y);\n    bRecording = button_record.pressed(touch.x, touch.y);\n     \n    bDoubleTapped = true;\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs&amp;amp; args){\n \n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 6: Pickers, Images, Cameras<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Introduction<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">We visited image and camera interaction this week by looking at (1) the openFrameworks extension of&nbsp;<code>UIImagePicker<\/code>,&nbsp;<code>ofxiPhoneImagePicker<\/code>, (2) the&nbsp;<code>ofImage<\/code>&nbsp;class, (3) the&nbsp;<code>ofVideoGrabber<\/code>&nbsp;and&nbsp;<code>ofVideoPlayer<\/code>&nbsp;classes, and (4) the&nbsp;<code>ofxCvColorImage<\/code>&nbsp;and&nbsp;<code>ofxCvGrayscaleImage<\/code>&nbsp;classes. Ultimately, we were interested in the pixels that represent the image in any of these classes, as moving those pixels from one class object to another enabled us to do different things. For instance, moving the pixels from an&nbsp;<code>ofVideoGrabber<\/code>&nbsp;to an&nbsp;<code>ofxCvColorImage<\/code>&nbsp;allowed us to convert the pixels to grayscale, storing them in an&nbsp;<code>ofxCvGrayscaleImage<\/code>. With the&nbsp;<code>ofxCvGrayscaleImage<\/code>, we were able to draw the grayscale version of the image on the screen. Of course, there are much more interesting things we can do with these classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Just like when we visited audio, we saw that this pixel information was defined by a pointer to memory, where the size of the memory was determined by the size of the image. The type of this memory is generally not a&nbsp;<code>float<\/code>&nbsp;like in audio, but an&nbsp;<code>unsigned char<\/code>, which is 8-bits or 256 possible values of information compared to the floating-point representation of 32-bits. We could access the pixels of any of these objects using a function called&nbsp;<code>getPixels()<\/code>&nbsp;(though not in the&nbsp;<code>ofxiPhoneImagePicker<\/code>&nbsp;class for some odd reason, we had to use just a variable called&nbsp;<code>pixels<\/code>:&nbsp;<code>myOfxiPhoneImagePicker.pixels<\/code>). Moving the pixels from one object to another entailed calling the&nbsp;<code>setFromPixels<\/code>&nbsp;method of one object. So for example, converting a ofVideoGrabber to an&nbsp;<code>ofxCvColorImage<\/code>&nbsp;could be done like so:&nbsp;<code>myOfxCvColorImage.setFromPixels(myOfVideoGrabber.getPixels(), widthOfImage, heightOfImage);<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We also had a tour of publishing on the app-store. This requires you to do a number of steps including getting a Distribution certification, Distribution provisioning profile, creating an app id, creating the app in&nbsp;<a href=\"https:\/\/itunesconnect.apple.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/itunesconnect.apple.com\/<\/a>, and making sure your app is built in XCode with code signing. Once you build the app, you run the \u201cApplication Loader\u201d stored in your \/Developer\/Applications folder, and submit the compressed application to Apple for approval. There is also a fairly good guide on the developer website when you visit the \u201ciOS Provisioning Portal\u201d and click on \u201cDistribution\u201d.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Homework: Try submitting an app we have already built, or extend one that we have built such as the drum pad recorders or the tape-cassette and then submit that.<\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 7: ofSoundPlayer and Accelerometer; GPS, MapKit, Annotations, and Interface Builder<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>ofSoundPlayer and Accelerometer<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">We first had a look at how openFrameworks gives us the information of the iPhone\/iPad accelerometer using the global variable\u00a0<code>ofxAccelerometer<\/code>. Extending the TouchAndAccelExample in the iPhoneSpecificExamples folder, we extended the simple ball-physics game to incorporate sound using\u00a0<code>ofSoundPlayer<\/code>. This class allows us to deal with sound without having to use the\u00a0<code>audioIn\/audioOut<\/code>\u00a0methods, however will only provide simple routines to deal with the audio. In order to get sound playback for the ball example, we had to understand when the ball hit a wall. We incorporated a simple boolean variable in the Ball.h class to tell us this, and then created a new SonicBall class which had a Ball object inside of it. We could have also extended the Ball class using\u00a0<em>inheritance<\/em>, but you can have a look at this on your own time. Note that when you create a C++ class using an iOS project, you have to make sure your \u201c.cpp\u201d files are renamed to \u201c.mm\u201d if they end up being refered to by any code using Objective-C. As a safe bet, just rename your \u201c.cpp\u201d files to \u201c.mm\u201d and it will work fine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Ball.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#define BOUNCE_FACTOR           0.7\n#define ACCELEROMETER_FORCE     0.2\n#define RADIUS                  20\n \n \nclass Ball {\npublic:\n    ofPoint pos;\n    ofPoint vel;\n    ofColor col;\n    ofColor touchCol;\n    bool bDragged, bHitWall;\n     \n    \/\/----------------------------------------------------------------  \n    void init(int id) {\n        bHitWall = false;\n         \n        pos.set(ofRandomWidth(), ofRandomHeight(), 0);\n        vel.set(ofRandomf(), ofRandomf(), 0);\n         \n        float val = ofRandom( 30, 100 );\n        col.set( val, val, val, 120 );\n         \n        if( id % 3 == 0  ){\n            touchCol.setHex(0x809d00);\n        }else if(  id % 3 == 1){\n            touchCol.setHex(0x009d88);\n        }else{\n            touchCol.setHex(0xf7941d);\n        }\n         \n        bDragged = false;\n    }\n     \n    \/\/----------------------------------------------------------------  \n    void update() {\n        bHitWall = false;\n         \n        vel.x += ACCELEROMETER_FORCE * ofxAccelerometer.getForce().x * ofRandomuf();\n        vel.y += -ACCELEROMETER_FORCE * ofxAccelerometer.getForce().y * ofRandomuf();        \/\/ this one is subtracted cos world Y is opposite to opengl Y\n         \n        \/\/ add vel to pos\n        pos += vel;\n         \n        \/\/ check boundaries\n        if(pos.x &amp;lt; RADIUS) {\n            pos.x = RADIUS;\n            vel.x *= -BOUNCE_FACTOR;\n            bHitWall = true;\n        } else if(pos.x &gt;= ofGetWidth() - RADIUS) {\n            pos.x = ofGetWidth() - RADIUS;\n            vel.x *= -BOUNCE_FACTOR;\n            bHitWall = true;\n        }\n         \n        if(pos.y &amp;lt; RADIUS) {\n            pos.y = RADIUS;\n            vel.y *= -BOUNCE_FACTOR;\n            bHitWall = true;\n        } else if(pos.y &gt;= ofGetHeight() - RADIUS) {\n            pos.y = ofGetHeight() - RADIUS;\n            vel.y *= -BOUNCE_FACTOR; \n            bHitWall = true;\n        }\n    }\n     \n    \/\/----------------------------------------------------------------\n    void draw() {\n        if( bDragged ){\n            ofSetColor(touchCol);\n            ofCircle(pos.x, pos.y, 80);\n        }else{\n            ofSetColor(col);        \n            ofCircle(pos.x, pos.y, RADIUS);\n        }\n    }\n     \n    \/\/----------------------------------------------------------------  \n    void moveTo(int x, int y) {\n        pos.set(x, y, 0);\n        vel.set(0, 0, 0);\n    }\n};\nSonicBall.h\nBe sure to add your own sound to the \u201cdata\u201d folder. I have grabbed one off of freesound.org.\n\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n#pragma once\n \n#include &quot;Ball.h&quot;\n \nclass SonicBall {\n     \npublic:\n    SonicBall()\n    {\n        sound.loadSound(&quot;106727__kantouth__cartoon-bing-low.wav&quot;);\n    }\n    void init(int id)\n    {\n        ball.init(id);\n    }\n    void update()\n    {\n        ball.update();\n        if(ball.bHitWall)\n        {\n            sound.setSpeed(sqrt(ball.vel.x*ball.vel.x + ball.vel.y*ball.vel.y));\n            sound.play();\n        }\n    }\n    void draw()\n    {\n        ball.draw();\n    }\n     \n    Ball ball;\n    ofSoundPlayer sound;\n     \n}#pragma once\n \n#define BOUNCE_FACTOR           0.7\n#define ACCELEROMETER_FORCE     0.2\n#define RADIUS                  20\n \n \nclass Ball {\npublic:\n    ofPoint pos;\n    ofPoint vel;\n    ofColor col;\n    ofColor touchCol;\n    bool bDragged, bHitWall;\n     \n    \/\/----------------------------------------------------------------  \n    void init(int id) {\n        bHitWall = false;\n         \n        pos.set(ofRandomWidth(), ofRandomHeight(), 0);\n        vel.set(ofRandomf(), ofRandomf(), 0);\n         \n        float val = ofRandom( 30, 100 );\n        col.set( val, val, val, 120 );\n         \n        if( id % 3 == 0  ){\n            touchCol.setHex(0x809d00);\n        }else if(  id % 3 == 1){\n            touchCol.setHex(0x009d88);\n        }else{\n            touchCol.setHex(0xf7941d);\n        }\n         \n        bDragged = false;\n    }\n     \n    \/\/----------------------------------------------------------------  \n    void update() {\n        bHitWall = false;\n         \n        vel.x += ACCELEROMETER_FORCE * ofxAccelerometer.getForce().x * ofRandomuf();\n        vel.y += -ACCELEROMETER_FORCE * ofxAccelerometer.getForce().y * ofRandomuf();        \/\/ this one is subtracted cos world Y is opposite to opengl Y\n         \n        \/\/ add vel to pos\n        pos += vel;\n         \n        \/\/ check boundaries\n        if(pos.x &amp;lt; RADIUS) {\n            pos.x = RADIUS;\n            vel.x *= -BOUNCE_FACTOR;\n            bHitWall = true;\n        } else if(pos.x &gt;= ofGetWidth() - RADIUS) {\n            pos.x = ofGetWidth() - RADIUS;\n            vel.x *= -BOUNCE_FACTOR;\n            bHitWall = true;\n        }\n         \n        if(pos.y &amp;lt; RADIUS) {\n            pos.y = RADIUS;\n            vel.y *= -BOUNCE_FACTOR;\n            bHitWall = true;\n        } else if(pos.y &gt;= ofGetHeight() - RADIUS) {\n            pos.y = ofGetHeight() - RADIUS;\n            vel.y *= -BOUNCE_FACTOR; \n            bHitWall = true;\n        }\n    }\n     \n    \/\/----------------------------------------------------------------\n    void draw() {\n        if( bDragged ){\n            ofSetColor(touchCol);\n            ofCircle(pos.x, pos.y, 80);\n        }else{\n            ofSetColor(col);        \n            ofCircle(pos.x, pos.y, RADIUS);\n        }\n    }\n     \n    \/\/----------------------------------------------------------------  \n    void moveTo(int x, int y) {\n        pos.set(x, y, 0);\n        vel.set(0, 0, 0);\n    }\n};\nSonicBall.h\nBe sure to add your own sound to the \u201cdata\u201d folder. I have grabbed one off of freesound.org.\n\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n#pragma once\n \n#include &quot;Ball.h&quot;\n \nclass SonicBall {\n     \npublic:\n    SonicBall()\n    {\n        sound.loadSound(&quot;106727__kantouth__cartoon-bing-low.wav&quot;);\n    }\n    void init(int id)\n    {\n        ball.init(id);\n    }\n    void update()\n    {\n        ball.update();\n        if(ball.bHitWall)\n        {\n            sound.setSpeed(sqrt(ball.vel.x*ball.vel.x + ball.vel.y*ball.vel.y));\n            sound.play();\n        }\n    }\n    void draw()\n    {\n        ball.draw();\n    }\n     \n    Ball ball;\n    ofSoundPlayer sound;\n     \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We just have to rename the portion in testApp that deal with \u201cBall\u201d to now deal with \u201cSonicBall\u201d, as we mimicked most of the functionality (except for moveTo, but you can do this on your own very easily).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n#include &quot;SonicBall.h&quot;\n \nclass testApp : public ofxiPhoneApp {\n     \npublic:\n    void setup();\n    void update();\n    void draw();\n    void exit();\n \n    void touchDown(int x, int y, int id);\n    void touchMoved(int x, int y, int id);\n    void touchUp(int x, int y, int id);\n    void touchDoubleTap(int x, int y, int id);\n    void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n     \n    void lostFocus();\n    void gotFocus();\n    void gotMemoryWarning();\n    void deviceOrientationChanged(int newOrientation);\n     \n    void gotMessage(ofMessage msg);\n     \n    ofImage arrow;\n     \n    vector &amp;lt;SonicBall&gt; balls;\n};\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){  \n    ofBackground(225, 225, 225);\n    ofSetCircleResolution(80);\n     \n    \/\/ register touch events\n    ofxRegisterMultitouch(this);\n     \n    \/\/ initialize the accelerometer\n    ofxAccelerometer.setup();\n     \n    \/\/iPhoneAlerts will be sent to this.\n    ofxiPhoneAlerts.addListener(this);\n     \n    balls.assign(10, SonicBall());\n     \n    arrow.loadImage(&quot;arrow.png&quot;);\n    arrow.setAnchorPercent(1.0, 0.5);\n     \n    \/\/ initialize all of the Ball particles\n    for(int i=0; i&amp;lt;balls.size(); i++){\n        balls&#x5B;i].init(i);\n    }\n}\n \n \n\/\/--------------------------------------------------------------\nvoid testApp::update() {\n    for(int i=0; i &amp;lt; balls.size(); i++){\n        balls&#x5B;i].update();\n    }\n    printf(&quot;x = %f   y = %f \\n&quot;, ofxAccelerometer.getForce().x, ofxAccelerometer.getForce().y);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw() {\n    ofSetColor(54);\n    ofDrawBitmapString(&quot;Multitouch and Accel Example&quot;, 10, 20);\n \n    float angle = 180 - RAD_TO_DEG * atan2( ofxAccelerometer.getForce().y, ofxAccelerometer.getForce().x );\n \n    ofEnableAlphaBlending();\n    ofSetColor(255);\n    ofPushMatrix();\n        ofTranslate(ofGetWidth()\/2, ofGetHeight()\/2, 0);\n        ofRotateZ(angle);\n        arrow.draw(0,0);\n    ofPopMatrix();\n \n    ofPushStyle();\n        ofEnableBlendMode(OF_BLENDMODE_MULTIPLY);\n        for(int i = 0; i&amp;lt; balls.size(); i++){\n            balls&#x5B;i].draw();\n        }\n    ofPopStyle();\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::exit() {\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(int x, int y, int id){\n    \/\/  printf(&quot;touch %i down at (%i,%i)\\n&quot;, id, x,y);\n    \/\/  balls&#x5B;id].moveTo(x, y);\n    \/\/  balls&#x5B;id].bDragged = true;\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(int x, int y, int id){\n    \/\/  printf(&quot;touch %i moved at (%i,%i)\\n&quot;, id, x, y);\n    \/\/  balls&#x5B;id].moveTo(x, y);\n    \/\/  balls&#x5B;id].bDragged = true;  \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(int x, int y, int id){\n    \/\/  balls&#x5B;id].bDragged = false;\n    \/\/  printf(&quot;touch %i up at (%i,%i)\\n&quot;, id, x, y);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(int x, int y, int id){\n    printf(&quot;touch %i double tap at (%i,%i)\\n&quot;, id, x, y);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::lostFocus() {\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotFocus() {\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMemoryWarning() {\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::deviceOrientationChanged(int newOrientation){\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs&amp;amp; args){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMessage(ofMessage msg){\n     \n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>GPS, MapKit, Annotations, and Interface Builder<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">The MapKit example likely just displays a gray screen with a circle and a line on it, and no map. To get the map to show, we have to change a few things. First, find the file in \/addons\/ofxiPhone\/src\/ES1Renderer.mm and look for the function resizeFromLayer. Change the first line of code to say:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer\n{   \n    layer.opaque = NO;  \/\/ &amp;lt;--- CHANGE THIS LINE OF CODE\n    \/\/ Allocate color buffer backing based on the current layer size\n    \/\/&#x5B;context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];\n     \n    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &amp;amp;backingWidth);\n    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RE\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Next, we had to edit the setup() function to get a clear background. I\u2019m not copying the code here but it is contained in a zip file at the end of this explanation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Interface Builder (IB) is a tool incorporated into the new Xcode 4 which used to be a separate application pre-Xcode 4. This allows us to build an interface with buttons, graphics, scroll views, navigation bars, tool bars, gestures, etc\u2026 using a incredibly UNINTUITIVE interface. However, after being shown how to use the interface builder and trying it out a few times for your self, you will find you are able to make very nice interfaces very quickly. Alternatively, you can disregard IB and use OpenGL drawing to build your interface, like we have done with the \u201cpadButton\u201d examples of Week 2-3. There are also existing openFrameworks addons that use code to build GUIs (e.g.:&nbsp;<a href=\"http:\/\/www.syedrezaali.com\/blog\/?p=2172\">ofxUI<\/a>), however, you will notice the aesthetic of these guis are very limited in the same as IB\u2019s aesthetic is, though in a different way. OpenGL interfaces built using openFrameworks are generally cross-platform, have rectangular buttons with sharp lines, and require a bit of hacking to get spaced well, and require you think in terms of code to personalize them to your taste. IB is Apple-only, is built using a graphical canvas, generally has the rounded buttons with the shiny button look, and can\u2019t be modified for your own purposes outside of what IB lets you do (which may be plenty). In either case, to create an aesthetic that pleases you, you can always design your own buttons using Photoshop etc\u2026 and use these as graphics for your buttons (recommended). IB lets you do this, and some openFrameworks GUI addons may also let you do this (I haven\u2019t tried ofxUI).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To begin creating our new interface with IB, create a new file of type \u201cView\u201d, which you will find under the \u201ciOS\/User Interface\u201d menu. Name the file something like \u201cMyGui\u201d and the final filename will have the .xib extension which we pronouce NIB. Also create another file of type \u201cObjective-C\u201d class and select to option to make this a subclass of \u201cUIViewController\u201d. Call the class something like \u201cMyGuiController\u201d. Now open up the IB by selecting the \u201cMyGui.xib\u201d file. This is where things get tricky if you haven\u2019t played with IB before. For those of you who missed class, perhaps I will upload a video when I get some time. What you need to do is tell the \u201cFile Owner\u201d of the \u201cMyGui.xib\u201d file to be the newly created \u201cMyGuiController\u201d. Select the 4th tab in the right-pane menu and change the class to match this new class name. Next, assign the View of the File Owner to be the already created View by control-dragging from File Owner to View in the left-pane menu. Now create a Toolbar and place it in the top or bottom of the view in the canvas. Also assign the button\u2019s select action to the File Owner by control dragging and choose the \u201cSelect\u201d action, calling it \u201ctakePhoto\u201d. In order to get this button\u2019s callback code, we can manually type in the code in our objective-C class, or again control-drag from the button to the Header and Source files of MyGuiController.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We also have to get our Objective-C class to talk to our testApp class by getting the pointer to the instance of testApp which is running. Luckily openFrameworks implements a global method ofGetAppPtr() which gives us this. We can therefore include a pointer to our app inside of our Objective-C class which allows us to call methods in the testApp class. Thus, we need to create methods in our testApp class which will become callbacks for our newly created button. I called mine something like \u201ctakePhoto\u201d, as I want the button to take a photo whenever it is pressed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, we need to tell the application about this new View. We remove the \u201cinitWithNib\u201d code from our objective-C class and instead have our testApp\u2019s setup() deal with the initialization of the view. The resulting project, code, objective-C class, and interface file is contained in this zip file:\u00a0<a href=\"http:\/\/archive.pkmital.com\/wp-content\/uploads\/2012\/01\/pkmMapKitGui.zip\">pkmMapKitGui<\/a>. I\u2019ve created 2 additional buttons in this example so you can see how the code looks like.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Week 8: Audio Synthesis and FFT, OSC Send and Receive<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>Audio Synthesis and FFT<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">We explored using a library developed at Goldsmiths by Mick Grierson and Chris Kiefer called&nbsp;<a href=\"https:\/\/github.com\/micknoise\/Maximilian\" target=\"_blank\" rel=\"noreferrer noopener\">Maximilian<\/a>. Download this project by locating the link for the \u201cZIP\u201d file on the github website. Looking through the Header file, \u201cmaximilian.h\u201d, we can see there are a variety of classes for modular synthesis and effects including: oscillators such as sine, triangle, square, pulse; delay lines; filters; and simple wave file reading with float access. We saw how to load files using the ofSoundPlayer and play them back, but we didn\u2019t have access to the \u201cfloat\u201d values of that signal, so we couldn\u2019t process them with delay lines or do anything other than what the ofSoundPlayer class defines. However, with maximilian, you can load wave files and process them to your heart\u2019s content.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start with a copy of the emptyExample in the iOS version of openFrameworks. We first include Maximilian into our project by dragging the \u201cmaximilian.h\u201d and \u201cmaximilian.cpp\u201d files into our \u201csrc\u201d folder and asking the dialog that pops up to \u201ccopy files into destination group\u201d.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"917\" height=\"339\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.39.24-PM.png\" alt=\"\" class=\"wp-image-2998\" srcset=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.39.24-PM.png 917w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.39.24-PM-800x296.png 800w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.39.24-PM-768x284.png 768w\" sizes=\"auto, (max-width: 917px) 100vw, 917px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Alternatively, we can create an addon in our openFrameworks directory such as \u201cof_preRelease_v007_iphone\/addons\/maximilian\u201d, and copy the files there. Then drag the folder \u201cmaximilian\u201d from the addons folder in Finder to the project in XCode.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you have your project setup to compile maximilian by doing the above steps, we tell our testApp.h to include the maximilian header file. We can then create some objects defined by maximilian and play with some basic synthesis.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We also had a look at finding the\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Fast_Fourier_transform\" target=\"_blank\">FFT<\/a>\u00a0of an audio signal. Using a library I have developed, we can easily find the Magnitudes and Phases of an audio signal, and using openFrameworks, visualize them. We have to download the 2 files from my\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/pkmital\/pkmFFT\" target=\"_blank\">github.com\/pkmital\/pkmFFT<\/a>, pkmFFT.h and pkmFFT.cpp, in order to begin using the library, and again copy them to our project, and include the header file. We also have to include a Framework called the Accelerate Framework. You can read about this framework in the Apple Developer documentation, but simply it allows you to do some very optimized Math operations. I make use of this library in calculating the FFT so that it is VERY fast. In order to add this framework, inside XCode, click on your project \u201cemptyExample\u201d in the left pane Project Navigator, then click your target, emptyExample in the pane just to the right of that one, and find the 4th tab, Build Phases. You want to find the section, \u201cLink Binary With Libraries\u201d, and click the \u201c+\u201d sign to add the Accelerate framework. It should be listed under the most recent iOS SDK, and it should be the first option. The picture below is meant to show this navigation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1061\" height=\"503\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.47.34-PM.png\" alt=\"\" class=\"wp-image-2999\" srcset=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.47.34-PM.png 1061w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.47.34-PM-800x379.png 800w, https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.47.34-PM-768x364.png 768w\" sizes=\"auto, (max-width: 1061px) 100vw, 1061px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once you have the library loaded, and the maximilian.h, maximilian.cpp, pkmFFT.h, and pkmFFT.cpp files loaded, your project navigator will look something like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"260\" height=\"325\" src=\"https:\/\/pkmital.com\/home\/wp-content\/uploads\/2023\/08\/Screen-Shot-2012-03-28-at-12.47.21-PM.png\" alt=\"\" class=\"wp-image-3001\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The code we developed in class is copied below. Feel free to experiment with other synthesis techniques, or loading wave files to manipulate your own audio files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n#include &quot;maximilian.h&quot;\n#include &quot;pkmFFT.h&quot;\n \nclass testApp : public ofxiPhoneApp {\n     \npublic:\n    void setup();\n    void update();\n    void draw();\n    void exit();\n     \n    void audioOut(float *buffer, int size, int channels);\n     \n    void touchDown(ofTouchEventArgs &amp;amp;touch);\n    void touchMoved(ofTouchEventArgs &amp;amp;touch);\n    void touchUp(ofTouchEventArgs &amp;amp;touch);\n    void touchDoubleTap(ofTouchEventArgs &amp;amp;touch);\n    void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n \n    void lostFocus();\n    void gotFocus();\n    void gotMemoryWarning();\n    void deviceOrientationChanged(int newOrientation);\n \n    maxiOsc osc1, osc2;\n    maxiDelayline dl;\n     \n    pkmFFT *fft;\n    float *allocated_magnitude_buffer;\n    float *allocated_phase_buffer;\n     \n     \n    int x, y;\n     \n    int sampleRate, frameSize;\n     \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){  \n    \/\/ register touch events\n    ofRegisterTouchEvents(this);\n     \n    \/\/ initialize the accelerometer\n    ofxAccelerometer.setup();\n     \n    \/\/iPhoneAlerts will be sent to this.\n    ofxiPhoneAlerts.addListener(this);\n     \n    \/\/If you want a landscape oreintation \n    \/\/iPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);\n     \n    ofBackground(127,127,127);\n     \n    sampleRate = 44100;\n    frameSize = 1024;\n     \n    fft = new pkmFFT(frameSize);\n    allocated_magnitude_buffer =  \n            (float *) malloc (sizeof(float) * frameSize \/ 2);\n    allocated_phase_buffer =  \n            (float *) malloc (sizeof(float) * frameSize \/ 2);\n     \n    ofSoundStreamSetup(1, 0, sampleRate, frameSize, 4);\n}\n \nvoid testApp::audioOut(float *buffer, int size, int channels) {\n    for (int i = 0; i &amp;lt; frameSize; i++) {\n        buffer&#x5B;i] = dl.dl(osc1.sinewave(x*100), \n                          8000, \n                          MAX(0.1, y \/ (float)ofGetHeight()));\n    }\n     \n    fft-&gt;forward(0, \n                 buffer,\n                 allocated_magnitude_buffer, \n                 allocated_phase_buffer);\n}\n \n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n     \n    ofPushMatrix();\n    ofTranslate(0, ofGetHeight() \/ 2);\n    float width_step = ofGetWidth() \/ (float)(frameSize \/ 2);\n    for (int i = 1; i &amp;lt; frameSize \/ 2; i++) {\n        ofLine((i-1)*width_step, -allocated_magnitude_buffer&#x5B;i-1] * 20, \n               i*width_step, -allocated_magnitude_buffer&#x5B;i] * 20);\n    } \n    ofPopMatrix();\n     \n}\n \n \n \n\/\/--------------------------------------------------------------\nvoid testApp::exit(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp;touch){\n    x = touch.x;\n    y = touch.y;\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp;touch){\n    x = touch.x;\n    y = touch.y;\n     \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::lostFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMemoryWarning(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::deviceOrientationChanged(int newOrientation){\n \n}\n \n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs&amp;amp; args){\n \n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<p class=\"wp-block-paragraph\"><strong>OSC Send and Receive<\/strong><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p class=\"wp-block-paragraph\">We can send signals between devices using our internet connection with a wonderful warpper called OpenSoundControl, which is built on-top of UDP or TCP. For example, from our iPhone which is connected to a router wirelessly, we can send the x,y positions of the user touch callbacks to our Laptop connected on the same router. Or vice-versa, perhaps we have a camera tracking environment on our laptop, and we want to send the information of a tracked person to our iPhone. One device has to be the sender, and another the receiver. We could also create an ad-hoc network between the two devices (e.g.&nbsp;<a href=\"http:\/\/lifehacker.com\/283088\/share-your-macs-internet-connection-wirelessly\" target=\"_blank\" rel=\"noreferrer noopener\">internet sharing<\/a>). We denote the receiver the HOST.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s try it with our Laptop\/Desktop being the sender, and our iPhone\/iPad being the HOST or receiver. In the OSX branch of openFrameworks, copy the oscSenderExample inside the \u201cof\/apps\/addonsExamples\u201d folder to your own project directory. Make sure we set the HOST variable to be our iPhone\u2019s IP address. Here is the code:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxOsc.h&quot;\n \n#define HOST &quot;172.29.1.138&quot;  \/\/ change to our iphone&#039;s ip address\n#define PORT 12345 \/\/ and the oscReceiver port number\n \n\/\/--------------------------------------------------------\nclass testApp : public ofBaseApp{\n \n    public:\n \n        void setup();\n        void update();\n        void draw();\n         \n        void keyPressed(int key);\n        void keyReleased(int key);\n        void mouseMoved(int x, int y );\n        void mouseDragged(int x, int y, int button);\n        void mousePressed(int x, int y, int button);\n        void mouseReleased(int x, int y, int button);\n        void windowResized(int w, int h);\n        void dragEvent(ofDragInfo dragInfo);\n        void gotMessage(ofMessage msg);     \n \n        ofTrueTypeFont      font;\n        ofxOscSender sender;\n         \n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.cpp<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n \n    ofBackground( 40, 100, 40 );\n \n    \/\/ open an outgoing connection to HOST:PORT\n    sender.setup( HOST, PORT );\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n    ofxOscMessage m;\n    m.setAddress( &quot;\/mouse\/position&quot; );\n    m.addIntArg( mouseX );\n    m.addIntArg( mouseY );\n    sender.sendMessage( m );\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::keyPressed  (int key){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::keyReleased(int key){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseMoved(int x, int y ){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseDragged(int x, int y, int button){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mousePressed(int x, int y, int button){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::mouseReleased(int x, int y, int button){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::windowResized(int w, int h){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMessage(ofMessage msg){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::dragEvent(ofDragInfo dragInfo){ \n \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Once we compile this code, we leave the application running on our desktop environment. Now we copy the oscReceiverExample in the iOS branch of openFrameworks and work from there. Here is the code for the iPhone application that will run on our phone:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.h<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#pragma once\n \n#include &quot;ofMain.h&quot;\n#include &quot;ofxiPhone.h&quot;\n#include &quot;ofxiPhoneExtras.h&quot;\n#include &quot;ofxOsc.h&quot;\n \n\/\/ listen on port 12345\n#define PORT 12345\n#define NUM_MSG_STRINGS 20\n \nclass testApp : public ofxiPhoneApp {\n \n    public:\n        void setup();\n        void update();\n        void draw();\n        void exit();\n         \n        void touchDown(ofTouchEventArgs &amp;amp;touch);\n        void touchMoved(ofTouchEventArgs &amp;amp;touch);\n        void touchUp(ofTouchEventArgs &amp;amp;touch);\n        void touchDoubleTap(ofTouchEventArgs &amp;amp;touch);\n        void touchCancelled(ofTouchEventArgs &amp;amp;touch);\n \n        void lostFocus();\n        void gotFocus();\n        void gotMemoryWarning();\n        void deviceOrientationChanged(int newOrientation);\n \n        ofxOscReceiver  receiver;\n        int             mouseX, mouseY;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>testApp.mm<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n#include &quot;testApp.h&quot;\n \n\/\/--------------------------------------------------------------\nvoid testApp::setup(){\n    ofSetOrientation(OF_ORIENTATION_90_LEFT);\n \n    \/\/ listen on the given port\n    cout &amp;lt;&amp;lt; &quot;listening for osc messages on port &quot; &amp;lt;&amp;lt; PORT &amp;lt;&amp;lt; &quot;\\n&quot;;\n    receiver.setup( PORT );\n    mouseX = 0;\n    mouseY = 0;\n    ofBackground( 0 );\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::update(){\n    \/\/ check for waiting messages\n    while( receiver.hasWaitingMessages() ){\n        \/\/ get the next message\n        ofxOscMessage m;\n        receiver.getNextMessage( &amp;amp;m );\n \n        \/\/ check for mouse moved message\n        if( m.getAddress() == &quot;\/mouse\/position&quot; ){\n            \/\/ both the arguments are int32&#039;s\n            mouseX = m.getArgAsInt32( 0 );\n            mouseY = m.getArgAsInt32( 1 );\n        }\n    }   \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::draw(){\n    ofBackground(0);\n    ofSphere(mouseX, mouseY, 0, 50);\n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::exit(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDown(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchMoved(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchUp(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchDoubleTap(ofTouchEventArgs &amp;amp;touch){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::lostFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotFocus(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::gotMemoryWarning(){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::deviceOrientationChanged(int newOrientation){\n \n}\n \n\/\/--------------------------------------------------------------\nvoid testApp::touchCancelled(ofTouchEventArgs&amp;amp; args){\n \n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">With each application running on their respective devices, we should see a Sphere on our phone move based on our Laptop\/Desktop\u2019s mouse movement. If it isn\u2019t working, it is very likely it is a network issue. Make sure you turn off your Firewalls on each device, and double check the IP address and port numbers. Try a different port if it still doesn\u2019t work, something above 10000. This is just a simple idea, but can be extended to your own purposes to send any control data you wish. Going in the other direction, you can use your own Laptop\/Desktop with an interactive touchPad: your iPhone or iPad.<\/p>\n<\/div>\n<\/div>\n","protected":false},"featured_media":3037,"template":"","categories":[15],"teaching-type":[396],"class_list":["post-2984","pkm_teaching","type-pkm_teaching","status-publish","has-post-thumbnail","hentry","category-teaching","teaching-type-creative-coding"],"acf":[],"_links":{"self":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/pkm_teaching\/2984","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/pkm_teaching"}],"about":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/types\/pkm_teaching"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/media\/3037"}],"wp:attachment":[{"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/media?parent=2984"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/categories?post=2984"},{"taxonomy":"teaching-type","embeddable":true,"href":"https:\/\/pkmital.com\/home\/wp-json\/wp\/v2\/teaching-type?post=2984"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}