<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Wm Leler on Medium]]></title>
        <description><![CDATA[Stories by Wm Leler on Medium]]></description>
        <link>https://medium.com/@wmleler1?source=rss-64fb7daa2629------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*c8OAb9nT35XgY56T.</url>
            <title>Stories by Wm Leler on Medium</title>
            <link>https://medium.com/@wmleler1?source=rss-64fb7daa2629------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 22:57:57 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@wmleler1/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[DIYVS Low-Cost Virtual Studio Device]]></title>
            <link>https://wmleler1.medium.com/diyvs-low-cost-virtual-studio-device-7166e8901878?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/7166e8901878</guid>
            <category><![CDATA[sound]]></category>
            <category><![CDATA[audio]]></category>
            <category><![CDATA[pandemic]]></category>
            <category><![CDATA[diy]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Sun, 07 Feb 2021 04:08:09 GMT</pubDate>
            <atom:updated>2021-02-23T01:03:31.554Z</atom:updated>
            <content:encoded><![CDATA[<p>Assemble your own JackTrip Virtual Studio and save money</p><p><em>Note: The JackTrip Virtual Studio software has been updated so that this project will work with most USB audio interfaces and audio adapters. There is no longer any need to modify or update this software yourself.</em></p><h3>Introduction</h3><p>Until recently, solutions for playing music together remotely have primarily been software-based. Initially, groups of <strong>telemusicians</strong> tried to use video conferencing applications such as Zoom, but that didn’t work out very well because of excessive audio delays.</p><p>Purpose-built applications, such as <a href="https://jamulus.io/">Jamulus</a>, <a href="https://jamkazam.com/">JamKazam</a>, and <a href="https://jacktrip.org/">JackTrip</a> have become popular, running on general-purpose computers (Macintosh, Windows, or Linux). However, these computers still create audio delay problems because they are constantly interrupting themselves to do other things — downloading email, performing backups, beeping when notifications arrive, checking social media, and updating software — which disrupts the music. Also, such programs are difficult to install and set up for good results. Running these applications on a dedicated computer (such as a <a href="https://www.raspberrypi.org/">Raspberry Pi</a>) solves many of these problems, but it requires technical skills for audio, and for computer hardware and software.</p><p>The JackTrip Foundation reduces the need for deep technical skills by creating and selling a dedicated <a href="https://en.wikipedia.org/wiki/Computer_appliance"><em>computer appliance</em></a>, called the <a href="https://www.jacktrip.org/studio.html">JackTrip Virtual Studio device</a>, combining a fast but inexpensive Raspberry Pi computer with a low <a href="https://en.wikipedia.org/wiki/Latency_(engineering)">latency</a> audio interface, with all the software pre-installed and automatically updated. This device has a friendly user interface, and is configured to connect to servers managed by the JackTrip Foundation (and others).</p><p>Because of its low latency and ease of use, the JackTrip Virtual Studio is fast becoming the method of choice for telemusicians — it is already used by groups containing hundreds of players and singers. The current <a href="https://www.jacktrip.org/studio.html">stock JackTrip Virtual Studio device</a> (the “device”) is an amazing piece of hardware. Its benefits include:</p><ul><li>Extremely low latency, less than 1mS (millisecond) delay. Tested against audio interfaces costing much more, and it has demonstrated superior <a href="https://www.jacktrip.org/technology.html">latency and jitter</a> specs, both of which can be extremely important when musicians want to create professional-quality music over the internet.</li><li>It is fully supported by the <a href="https://www.jacktrip.org/">JackTrip Foundation</a>, whose goal is to produce the easiest solution to the myriad problems of playing music together over the internet and still get the best sound possible.</li><li>It is FCC compliant to avoid radio interference, which is important for professional-level sound, and required when selling end-user electronics.</li></ul><p>The stock device costs $150 on Amazon, which is surprisingly low compared to most high quality audio equipment. For example, commercial audio interfaces can cost hundreds of dollars, and yet this affordable device contains both an audio interface and a powerful computer with a gigabit internet connection.</p><p>At the same time, the key software that runs on the Virtual Studio device, JackTrip, <a href="https://github.com/jacktrip/jacktrip">is open source</a>, and it has always been possible for advanced technical hobbyists to build their own device. In fact, the <a href="https://jacktrip.zendesk.com/hc/en-us/sections/360009752894-Building-Your-Own-Device">JackTrip documentation</a> provides information about how to do just that. But as the Virtual Studio has started to become popular, we have noticed a substantial gap between professional musicians (who want the highest quality), and the technological hobbyists who have the skills to build the hardware and software they want at lower cost. This gap includes:</p><ul><li>Amateur musicians, who don’t necessarily need the absolute highest quality of sound. They just want to be able to sing and play together, or jam with other musicians for fun, but don’t want to spend hundreds of dollars on the necessary equipment.</li><li>Some professional musicians, who just need something to allow them to practice together when it is difficult (or dangerous) to get together in person.</li><li>Audio and music enthusiasts who already own audio interfaces for computers and want to use that hardware to play remotely, but don’t have the technical skills to do that themselves.</li></ul><p>With the pandemic, this gap has become huge. There is strong demand for a lower cost, but still good solution that is accessible to people who are not necessarily technically sophisticated.</p><h3>DIYVS</h3><p>The solution is to take advantage of audio components that have mostly been created for other markets (like computer gaming) that are relatively inexpensive but are of sufficient quality. Alternatively, utilize audio interfaces, which many musicians already have and like. These allow different audio equipment to be combined with the inexpensive but powerful computer board already used in the high-end device, and meet the needs of the users in the gap.</p><p>Users will do final assembly themselves, so it will qualify as a hobbyist device and thus avoid FCC (and other countries’) <a href="https://www.raspberrypi.org/blog/raspberry-pi-integrator-programme/">compliance testing</a>, which would be prohibitively expensive because of the myriad permutations of audio equipment that would need to be tested. The individual components are FCC compliant, so there should not be any interference problems.</p><p>DIYVS can also be less expensive because it does not include commercial-level support. As with many new products, support is being done by the existing, fast-growing community of users who have already built their own Virtual Studio, and who are already well-connected with other musicians, both professional and amateur. (I know this because I am one of the many unpaid volunteers who are helping to support the Virtual Studio).</p><p>This project is named DIYVS (for “Do It Yourself Virtual Studio” (pronounced DYE-vis). This article tells you how to build one yourself. The parts are all off-the-shelf and can be purchased online. Assembling the parts takes an hour or less, even for people with only basic computer skills.</p><h3>Parts List</h3><p>These parts are suggested examples. You can purchase from other vendors (for example, <a href="https://www.sweetwater.com/">Sweetwater</a> and <a href="https://www.monoprice.com/">Monoprice</a>), or even other brands. Prices quoted are in US dollars, not including any sales taxes or shipping costs. It should be easy to find everything you need almost anywhere in the world.</p><h4>Raspberry Pi 4 Model B, with 2GB of RAM</h4><p>You can buy this for $35, from one of the vendors listed on <a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/">raspberrypi.org</a>. Amazon has them too, but at higher prices.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/372/0*6KjGuTI3KyMOpVfH" /></figure><h4>Metal Case</h4><p>A metal case is recommended for keeping your audio free of hum and noise. Amazon carries an <a href="https://www.amazon.com/GeeekPi-Raspberry-Aluminum-Enclosure-Heatsink/dp/B07HP21TPX/ref=sr_1_20">aluminum case made by GeeekPi</a> for $15.99 that also includes a power supply with an on/off switch, some stick-on heatsinks, a fan (which you don’t need to use), a small screwdriver for the screws, and instructions on how to assemble it:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/0*P3ddf0kjHlGQ-mTn" /></figure><p>Amazon also has a <a href="https://www.amazon.com/Vilros-Raspberry-Fan-Cooled-Heavy-Duty-Aluminum/dp/B07XTRFD3Z/ref=sr_1_6">similar package from Vilros</a> that includes the Raspberry Pi, plus a monitor cable, all for $66.99. Most of the vendors recommended on <a href="https://en.wikipedia.org/wiki/Latency_(engineering)">raspberrypi.org</a> also sell Raspberry Pi starter packages.</p><h4>Power Supply</h4><p>If not included with your case, you can buy a power supply by itself <a href="https://www.raspberrypi.org/products/type-c-power-supply/">for around $8</a> (not including an on/off switch). You should not skimp by using a power supply meant for a phone (even if you have a spare one lying around).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/0*gXwWWihll741cVs4" /></figure><p>Alternatively, <a href="https://www.amazon.com/CanaKit-Raspberry-Power-Supply-PiSwitch/dp/B07TSFYXBC/ref=pd_lpo_147_t_0/145-5762126-3804418">Canakit sells</a> an approved power supply with slightly higher power and a convenient on/off switch for $10.99 on Amazon.</p><h4>Micro SD card</h4><blockquote>Note that the JackTrip Foundation is about to start selling Micro SD cards already containing the needed software. They will look something like the following image, with the JackTrip logo. I will update this article when that happens. Until then, you will need to get a blank card and add the software to it yourself. Or you might want to do it yourself if you have a spare Micro SD card. This article explains how to do that.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/237/0*g8AaJ3cwlsjwcrWA" /></figure><p>You need at least 2GB, but the smallest ones for sale nowadays seem to be 8GB, and 16GB cards are now generally less expensive than 8GB ones. You can also use 32GB cards, but if you want to use anything 64GB or larger you will have to reformat it, so stick with something smaller if you can (probably 16GB or 32GB).</p><p>Your card should be at least Class 10 (a measure of the speed of the card), as shown by the 10 placed inside the letter C, shown on the SanDisk card in the figure below. Cards like the Samsung, below, which instead have a number placed inside a letter U, are at least Class 10 and will be slightly faster to boot up. Here’s a <a href="https://www.tomshardware.com/best-picks/raspberry-pi-microsd-cards">comparison of various Micro SD cards</a>, including their speed on a Raspberry Pi 4B (for this project, you will be most concerned about boot times).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/593/1*3iEf240UT9E6ntdlh-4oQA.png" /></figure><p>You should buy a brand of card that is known to be good, as there have been lots of substandard cards sold. SanDisk, Samsung, Micro Center, Kingston, Patriot, Pioneer, and Transcend are good brands. The card shown above by SanDisk can be <a href="https://www.amazon.com/Sandisk-Ultra-Micro-UHS-I-Adapter/dp/B073K14CVB/ref=sr_1_4">bought from Amazon</a> for $6.19, and it even includes an adapter card, which you might need. The Samsung card has twice the capacity, is faster, and lasts longer, and <a href="https://www.amazon.com/Samsung-Endurance-32GB-Micro-Adapter/dp/B07B98GXQT/ref=sr_1_3">Amazon sells it</a> for $8.99 (also including an adapter).</p><h4>USB Audio Adapter or Audio Interface</h4><p>A big advantage of building your own Virtual Studio device is that you can use other audio interfaces and adapters, possibly including ones you already have. Here is a <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360055205273-Tested-Sound-Cards">list of audio adapter and audio interfaces</a> that have been tested by the JackTrip Foundation to work with the Virtual Studio software. For this project we are focusing on those with a USB connector. Even when limited to audio interfaces that use USB connectors, there are literally hundreds of them out there. If you find one that works, please send a message to me about it.</p><p>These audio devices are divided into several kinds: Audio Adapters (sometimes called external sound cards), Audio Interfaces (more expensive), and USB mixers (also expensive).</p><h4>Audio Adapters</h4><p>Audio adapters are designed as external sound cards for computers. These are meant for gaming and listening to music, and are quite popular, so they are relatively inexpensive (around $5 to $30). I’ve compiled <a href="https://docs.google.com/spreadsheets/d/1mk4QDBthXkw2ADtNoLW6-0YZn7r-SQ6-M_FZhO9BjLg/edit?usp=sharing">data on latency and noise floor</a> for these adapters.</p><p>On most of these, the microphone input is strictly mono, but using a (stereo) TRS jack. Unless otherwise noted, the input and output volumes are adjusted using the JackTrip web app, and the adapter supplies <a href="https://www.shure.com/en-US/performance-production/louder/shure-tech-tip-phantom-power-vs-bias-voltage">bias power</a>, so it can be used with condenser microphones.</p><p><strong>A. </strong><a href="https://www.amazon.com/Sabrent-Aluminum-External-Adapter-AU-EMCB/dp/B00XM883BK/ref=sr_1_4"><strong>Sabrent Aluminum USB External Stereo Sound Adapter</strong></a></p><p>Pros: low cost — $7.99 on Amazon, metal case (assuming you buy the aluminum version, which is the same price as the plastic case), reasonable latency, and includes a USB extension cable. I have one and it works just fine. Cons: some people complain that it sounds scratchy. I think this might be because it has high gain on the microphone, which can cause it to overload and clip the JackTrip server. Try turning down the “Input Volume” on the web app to around 50 to 60 and see if that solves the problem.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/0*0W-dfg8yxk0KhO6B" /></figure><p><strong>B. </strong><a href="https://www.amazon.com/gp/product/B01N905VOY/ref=ppx_yo_dt_b_asin_title_o01_s00"><strong>UGREEN USB Audio Adapter External Stereo Sound Card</strong></a></p><p>$13.99 on Amazon. Lower noise, can set Input Volume on the web app to around 80.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/455/0*EG1qWmGcmRb-7XdR" /></figure><p><strong>C. </strong><a href="https://www.amazon.com/Syba-external-Adapter-Windows-C-Media/dp/B001MSS6CS/ref=sr_1_3"><strong>Syba external USB Stereo Sound Adapter</strong></a></p><p>$8.99 on Amazon. Works OK.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/439/0*JZxo9a6j82GHzbqk" /></figure><p>D. <a href="https://www.amazon.com/gp/product/B07RV6VBNR/ref=ppx_yo_dt_b_asin_title_o02_s00">DuKabel USB Audio Adapter for Gaming Headset</a></p><p>$9.99 on Amazon, metal case, cloth braided cables. Has high gain and poor noise floor, so try setting the Input Volume on the web app to around 60. If you turn it up higher, you will hear noise (hiss).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/355/0*pc7w2omvsQXSqIA4" /></figure><p>E. <a href="https://www.amazon.com/gp/product/B00F7120TQ/ref=ppx_yo_dt_b_asin_title_o00_s00">StarTech.com USB Sound Card w/SPDIF Digital Audio &amp; Stereo Mic</a></p><p>$30 on Amazon. Has multiple sample rates (44.1/48/96 KHz), SPDIF digital output, a simple equalizer and the mic input is true stereo. It also has a physical output volume control (and the output volume can also be adjusted from the JackTrip web app).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/329/0*6O4xL87pSM4azLoZ" /></figure><h4>Audio Interfaces</h4><p>High quality audio interfaces typically include XLR microphone connectors, phantom power (so you can use condenser mics), clipping indicators, and level controls for both the microphone inputs and headphone output. Most audio interfaces include multiple inputs; for example, if you want an input for a musical instrument pickup in addition to a microphone input for your voice. These run from $50 on up to more than a thousand dollars. If you use one of these, you will set your volume levels on the interface, not using the JackTrip web app.</p><p><strong>F. </strong><a href="https://www.amazon.com/Focusrite-Scarlett-Audio-Interface-Tools/dp/B07QR73T66/ref=sr_1_4"><strong>Focusrite Scarlett 2i2</strong></a></p><p>A very popular audio interface. It is currently selling for $159.99 on Amazon (the price has gone up due to heavy demand during the pandemic).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/0*Hl8JESHCeBL0ten1" /></figure><p><strong>G. </strong><a href="https://www.amazon.com/PreSonus-AudioBox-USB-Recording-System/dp/B08D8R6VFC/ref=sr_1_5"><strong>Presonus AudioBox USB 96</strong></a></p><p>$99.95 on Amazon.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/471/0*zdMkmm1DO6431uBL" /></figure><p>H. <a href="https://www.amazon.com/BEHRINGER-Audio-Interface-1-Channel-UM2/dp/B00EK1OTZC/ref=sr_1_2">Behringer UM2</a></p><p>Around $47 on Amazon. Handles one mic and one instrument pickup.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*rNIs0wglcBQRyNbK61a95Q.png" /></figure><h4>USB Mixers</h4><p>Mixers that connect to a computer using USB. I haven’t tested any of these yet, but if you have, let me know.</p><h3>Estimated Cost</h3><p>You can build this Virtual Studio device yourself with the Sabrent audio adapter for around $65. For comparison, the existing JackTrip Virtual Studio device sold on Amazon costs $159.98, (including the power supply). That’s <em>significantly less than half the cost</em>. And it can be even less if you already have some parts (like an audio interface or adapter). And you don’t need to buy the adapter cable to convert the two RCA jacks to a stereo TRS connector for headphones (saving you an additional $5), because the Sabrent audio adapter has a TRS headphone jack.</p><p>Another advantage of DIYVS is that you can customize it to your needs. For example, if you just want to practice together, or jam with friends, the low-cost Sabrent audio adapter will work just fine. Or later, if you need higher quality, you can upgrade to a powerful audio interface.</p><h3>Other Accessories</h3><p>Like the existing JackTrip Virtual Studio device, you will need some additional things before you can play music together remotely. The recommended accessories for the existing Virtual Studio device are listed in the <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360053801674-Virtual-Studio-Recommended-Accessories">JackTrip documentation</a>. This article mainly explains a few differences, and suggestions for low-cost but good quality alternative accessories.</p><p>I’ve also written another article that is <a href="https://wmleler1.medium.com/setting-up-your-virtual-studio-6a9fbea56f08">more detailed about possible accessories</a>. You should read it for more information.</p><h4>Ethernet Cable</h4><p>You will need an <a href="https://www.monoprice.com/search/index?keyword=Ethernet+cable">Ethernet cable</a>. It needs to be long enough to reach your Internet modem and router. Do not use WiFi.</p><h4>Headphones</h4><p>Do not use wireless (e.g., Bluetooth) headphones. As mentioned, you will not need the adapter cable.</p><p>If you use the Sabrent audio adapter, then headphones with a 3.5mm TRS plug will plug in directly. If you use an audio interface, most of them use a ¼ inch (6.35mm) TRS jack, so you will need an <a href="https://www.monoprice.com/product?p_id=7139">inexpensive adapter</a>.</p><p>Alternatively, <a href="https://www.amazon.com/SP3060-Isolating-Earphones-Headphones-BlackBerry/dp/B0170RBJ9Q/ref=sr_1_1_sspa">you can use wired earbuds</a>, not wireless, and preferably ones that do not include a built-in microphone.</p><h4>Microphone</h4><p>You can use (less expensive but good sounding) microphones meant for use with video cameras. These mics have the advantage that they are generally designed to work with more distant sounds, so they are more sensitive. They also generally use the same 3.5mm TRS plug used by the Sabrent, and many other audio adapters, so they can just be plugged in, with no adapter needed.</p><p>For example, I just bought a <a href="https://www.amazon.com/gp/product/B07P7P6M2J/ref=ppx_od_dt_b_asin_title_s00">MouKey video microphone from Amazon</a> for $17.42 (it is on sale for 30% off), which includes a foam cover, so it can be used for singing. It also includes a deadcat windscreen (to avoid wind noise when used outdoors), and a shock mount that can fit onto the hot shoe of a camera or onto a standard tripod. I use an inexpensive desktop camera tripod to hold it. It sounds amazingly good for its size and price.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/572/1*VgS2rUPIpnjtCKMU2pY9iQ.png" /></figure><p>Note that this mic will not work with the existing Virtual Studio device, because it requires bias power. But it will work fine with most Audio Adapters discussed in this article.</p><p>I also have a Sony stereo microphone, which plugs directly into the Sabrent (in mono), and sounds very good. Using the StarTech.com USB Sound Card, it works in true stereo! However, I don’t think Sony makes this mic anymore (I’ve had it for many years). But there are other stereo video camera microphones available if you want.</p><p>One downside of microphones meant for cameras is that they tend to have very short cables. But you can use longer, <a href="https://www.monoprice.com/product?p_id=18629">inexpensive 3.5mm TRS cables</a> instead.</p><p>Of course, you can also use many other styles and brands of microphones. Depending on their connector, you might need an adapter cable. And if you are using an audio interface (like the <a href="https://www.amazon.com/Focusrite-Scarlett-Audio-Interface-Tools/dp/B07QR73T66/ref=sr_1_4">Focusrite</a> or <a href="https://www.amazon.com/PreSonus-AudioBox-USB-Recording-System/dp/B08D8R6VFC/ref=sr_1_5">Presonus</a>), those have a balanced XLR jack for the microphone, so you might want to use a microphone with an XLR connector.</p><h3>Building your Virtual Studio device</h3><p>Building your own Virtual Studio device is actually surprisingly easy, even if you don’t have many technical skills. The only somewhat difficult thing is downloading the JackTrip Virtual Studio software and installing it on the Micro SD card and then inserting the card into the Raspberry Pi. If you need help, you can find a technical person who will do it for you (typically in exchange for some flat food, such as pizza).</p><blockquote>Note that soon it will be possible to purchase a Micro SD card with the Virtual Studio software already installed. At that point, assembling a DIYVS will be even simpler.</blockquote><h4>Tools you will need</h4><blockquote>If you purchase the Micro SD card with the Virtual Studio software already installed, you don’t need the last two tools. And you may not need a screwdriver if you buy the case mentioned earlier, because it includes the needed screwdriver).</blockquote><ul><li>If your case has screws (some don’t) and doesn’t come with a screwdriver, you may need a relatively small one.</li><li>If you are going to install the software on the Raspberry Pi, you will require a standard computer (Macintosh, Windows, or Linux).</li><li>To install the software on the Micro SD card, you need an SD card reader that can take Micro SD cards. Alternatively, if you have an adapter that adapts Micro SD cards to standard (full size) SD cards, you can use a regular SD card reader. You will only need this once, so you can possibly borrow it from someone. <a href="https://www.amazon.com/SmartQ-MicroSDXC-MicroSDHC-Windows-Android/dp/B07ZHNGM3G/ref=sr_1_22_sspa">Amazon sells an SD card reader</a> for $6.99 that takes both micro and standard SD cards, and can be used in computers with either USB-A or USB-C ports.</li></ul><h4>Steps</h4><blockquote>If you purchase the Micro SD card with the Virtual Studio software already installed, you don’t need to perform the first two steps.</blockquote><ul><li>Install <a href="https://www.balena.io/etcher/">Balena Etcher</a> onto your computer.</li><li>Download the <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360055205313-Virtual-Studio-Image-for-Raspberry-Pi">Virtual Studio image from this page</a>, and use Etcher to install it on the Micro SD card using an SD card reader.</li><li>Insert the Micro SD card into the Raspberry Pi board. Depending on your metal case, you may need to do this after you assemble the board into the case.</li><li>Assemble your Raspberry Pi, using the instructions that come with the case.</li><li>Plug in your audio adapter or audio interface to a USB port. The Raspberry Pi has both “SuperSpeed” USB 3.0 ports (which are light blue) and regular USB 2.0 ports (which are white or black). Either type will work just fine for audio, but you should use a USB 3.0 port (for slightly lower latency).</li><li>Plug in your microphone and headphones into the connectors on your audio adapter or audio interface.</li><li>Follow the instructions in “<a href="https://jacktrip.zendesk.com/hc/en-us/articles/360053538614-Getting-Started-with-a-Virtual-Studio-Device">Getting Started with a Virtual Studio Device</a>” starting with “Step 4. Connecting the Device to your Internet Router or Switch”. Alternatively, you can use the <a href="https://wmleler1.medium.com/setting-up-your-virtual-studio-6a9fbea56f08">instructions in my article</a> starting with “Virtual Studio cloud service”.</li></ul><h3>Setting Audio Levels</h3><p>An important thing in getting various USB audio devices to work well is to set your audio levels correctly. This is normally done using the JackTrip web app, accessed at <a href="https://app.jacktrip.org/devices">app.jacktrip.org</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hFZmATfVURvlrHV9" /></figure><p>The Input Volume controls the mic input of your audio adapter, and thus the volume of your microphone. Different microphones will have different output levels. For example, the MouKey microphone suggested earlier has a fairly high output, and if the Input Volume control is set too high it can overload the signal, causing scratching or popping sounds. If this happens, using the web app, turn down the Input Volume and/or turn off the Boost switch.</p><p>The Output Volume controls the headphone output of your audio adapter, and thus the volume you hear in your headphones. If you need more volume, using the web app, turn up the Output Volume and/or turn on the Boost switch.</p><p>Depending on your audio adapter and your headphones, you may still need more volume, in which case you have a couple of options. You can use a different audio adapter, including switching to an audio interface which has its own input and output volume controls (in which case you will not use the web app to set these levels).</p><p>Alternatively, you can buy a headphone amplifier (around $20 or so). Most headphone amplifiers can drive more than one set of headphones, in case you want to have more than one person playing or listening to music over the internet. The Behringer HA400 can drive up to four headphones with individual volume controls, and <a href="https://www.amazon.com/Behringer-HA400-Ultra-Compact-4-Channel-Headphone/dp/B000KIPT30/ref=sr_1_8">sells for $24 on Amazon</a>. It uses 6.35mm (¼ inch) TRS connectors instead of 3.5mm, so you will probably need some <a href="https://www.monoprice.com/product?p_id=7139">inexpensive adapters</a>.</p><p>Setting proper levels is especially important when you have people playing together who are using different USB audio devices, different microphones, or are standing at different distances from their microphones. Each player will need to set their own Input volume so everyone can be heard equally.</p><h3>Further Reading</h3><p><a href="https://www.jacktrip.org/studio.html">JackTrip Virtual Studio overview</a>.</p><p><a href="https://jacktrip.zendesk.com/hc/en-us/categories/360004519513-User-Guide-Virtual-Studio">JackTrip documentation for Virtual Studio</a>.</p><p><a href="https://www.jacktrip.org/">JackTrip website</a>.</p><p><a href="https://app.jacktrip.org/">Virtual Studio online app</a>.</p><p><a href="https://www.jacktrip.org/technology.html">Information about latency, lag, and jitter</a>.</p><p><a href="https://groups.google.com/forum/#!forum/jacktrip-users">JackTrip users email list</a>.</p><p>If you are confused about connector types (like TRS, XLR, RCA, etc.) <a href="https://www.sweetwater.com/insync/cable-buying-guide/">Sweetwater has a nice guide</a> to the common ones. Also see <a href="https://www.boxcast.com/blog/balanced-vs.-unbalanced-audio-whats-the-difference?fbclid=IwAR0pWOyLDs8oN3AWr8SfbSSs12I4EkNY-I7H0UwTEKVJioL8AfutmSg6sJw">this article</a> about balanced versus unbalanced cables.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7166e8901878" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setting up Your Virtual Studio]]></title>
            <link>https://wmleler1.medium.com/setting-up-your-virtual-studio-6a9fbea56f08?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/6a9fbea56f08</guid>
            <category><![CDATA[music]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[pandemic]]></category>
            <category><![CDATA[audio]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Sun, 31 Jan 2021 21:38:20 GMT</pubDate>
            <atom:updated>2021-02-05T01:35:42.077Z</atom:updated>
            <content:encoded><![CDATA[<h4>Easier jamming together over the Internet</h4><h3>Virtual Studio Project</h3><p>The goal of the Virtual Studio project is to make it much easier for musicians and singers to play music together remotely. Most current solutions require each player to install, configure, and update sophisticated software and hardware on their computers. This necessitates significant technical expertise — including for computers, real-time audio, and even networking — to attain acceptable results. Another big problem with playing music together remotely is avoiding audio delays, called <a href="https://www.jacktrip.org/technology.html"><strong>latency</strong></a>. The Virtual Studio project solves these problems in several ways:</p><ul><li>Virtual Studio is based on a self-contained device that includes the necessary computer hardware and software, pre-installed and configured.</li><li>The device updates its software automatically.</li><li>By standardizing the hardware and the software, latency can be better controlled. The only remaining delays are from the internet, namely distance delays caused by the speed of light and congestion delays caused by internet service providers.</li><li>The Virtual Studio project manages computer servers in the cloud, which connect the players together. These servers are easily configured and inexpensive. The project has servers in many locations, so you can choose servers that are nearby to reduce latency.</li></ul><p>This document walks you through the steps of buying and setting up your own Virtual Studio and getting a group of people connected to a server, so they can jam, practice, and even perform together.</p><blockquote>Even though you will be able to create music with other people remotely using Virtual Studio, it may not be the best way to record performances, as there will often be some latency between performers. Here is a <a href="https://youtu.be/r6Tcn1cIPtk">choir performance captured using Virtual Studio</a>. The director talks about how they did it after the first song.</blockquote><p>There are five main parts to Virtual Studio:</p><ol><li>The Virtual Studio device</li><li>A microphone — typically one but can be more</li><li>Headphones — to hear all the players in your group.</li><li>An internet connection — to connect to the Virtual Studio cloud service</li><li>An app — a simple web app running on any standard browser, to control everything</li></ol><p>Different musicians will have differing needs. You can customize your setup as you wish. This document will help you figure out your needs, and assist you in meeting them.</p><h3>The Virtual Studio Device</h3><p>The JackTrip Virtual Studio Device (“device”) is a small hardware device about the size of 3 decks of playing cards stacked. This is what it looks like, and it comes in <a href="https://www.hifiberry.com/shop/cases/steel-case-for-hifiberry-dac-pi-4-2/">white</a> or <a href="https://www.hifiberry.com/shop/cases/steel-case-for-hifiberry-dac-pi-4/">black</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*l1Ud9o4-n3qXhyaB" /></figure><blockquote>Inside the metal case are two boards. The main board is a <a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/">Raspberry Pi 4 Model B</a> with 2GB of RAM. This board costs only $35 but is basically a full computer almost as powerful as a laptop or even a reasonable desktop computer. The second board is a <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360055205193-Recommended-Build-HiFiBerry-ADC-DAC-Pro">HiFiBerry ADC DAC+ Pro</a>, a very <a href="https://www.jacktrip.org/technology.html">low latency</a> analog-to-digital (ADC) and digital-to-analog (DAC) sound board. There is also a 16 GB Micro SD flash memory card containing the <a href="https://www.jacktrip.org/">Raspberry Pi OS</a> (the <a href="https://www.raspbian.org/">Rasbian</a> version of <a href="https://en.wikipedia.org/wiki/Linux">Linux</a>) and the <a href="https://www.jacktrip.org/">JackTrip software</a>, pre-installed.</blockquote><p>Here is the box with labels showing the connectors we will be using:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*XRZvIt1PZaHsk3Yu" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rdunMslS3pptgK-b" /></figure><ul><li><strong>NET</strong> — Ethernet socket used for the Internet connection.</li><li><strong>MIC</strong> — ⅛ inch (3.5mm) TRS input from a microphone (or from a mixer or audio interface).</li><li><strong>AUDIO OUT</strong> — Two RCA jacks; red is the right channel. Output to headphones (or optional headphone amplifier).</li><li><strong>POWER</strong> — USB-C jack to connect to a power supply.</li></ul><p><a href="https://www.amazon.com/dp/B08L9LDW35">You can buy this from Amazon</a> for $150. If it is out of stock, check back. They are in demand right now, but they become available frequently. Things should get better in the future.</p><p>If you have a group of more than 20 people who want to buy these, you can get them directly from the <a href="/service/mailto:sales@jacktrip.org">Virtual Studio Foundation</a>.</p><blockquote>When you receive the device, shake it to make sure there are no loose screws inside. If there are any, you need to open the box. You’ll need a small Phillips head screwdriver. Here are the <a href="https://www.hifiberry.com/docs/hardware/steel-case-assembly/">instructions for assembling the case</a>. Follow them backwards to disassemble it, pulling the side with the RCA jacks (labeled “Audio out” above) slightly outward to disengage the case from the jacks. Replace any loose screws and tighten all screws, both inside and outside the case.</blockquote><p>If you have technical skills, you can build this device yourself. See the section “Building a Virtual Server device” below.</p><p>If you buy this device from Amazon, you get nothing else. You will also need a power supply and an Ethernet cable.</p><h4>Power Supply</h4><p>This plugs into a regular wall power socket and supplies power to the device. The power input on the Virtual Studio device is a USB-C socket, but is used for power only. You should not use a mobile phone charger for the power supply, instead use one of the official <a href="https://www.raspberrypi.org/products/type-c-power-supply/">Raspberry Pi 4 power supplies</a>. You should be able to get one for $8 (plus shipping).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/0*hDvWKqpW-TT_nnvg" /></figure><p>Make sure you specify the correct model and region (US, UK, EU, AU). Check to be sure the plug is the right one you need. You can also pick a black or white power supply (to match your device case).</p><p><a href="https://www.amazon.com/CanaKit-Raspberry-Power-Supply-PiSwitch/dp/B07TSFYXBC/ref=pd_lpo_147_t_0/145-5762126-3804418">Canakit also sells</a> an approved power supply with slightly higher power and a convenient on/off switch for $10.99 on Amazon.</p><h4>Internet via Wired Ethernet</h4><p>The Virtual Studio device <strong>should not be connected to the internet via WiFi</strong>. WiFi can cause excessive latency and jitter. Note that this is only a problem for hardware that is processing or transmitting audio. Your other connected devices — including the computer, tablet, or phone whose browser will run the web app to control the Virtual Studio device — can use WiFi if desired (or be connected direct into the hub/switch).</p><p>You will connect the device to the internet using an Ethernet cable (pictured below). The length you need depends on how far away your internet router will be from your Virtual Studio device. Ethernet cable lengths up to around 100 feet will work, but you should use a cable relatively close to the shortest length you need.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/380/0*sRzwLvEWBUGw_aLg" /></figure><blockquote>The speed of Ethernet cable is called its “Category” (abbreviated “Cat”). Cat 5 supports 100 Mbps internet. Cat 5e and Cat 6 support gigabit internet. If you are buying a new cable, I recommend you buy Cat 6 or Cat 6A. Cat 7 and Cat 8 will also work, but are overkill.</blockquote><p>Monoprice sells Cat 6 in lengths up to 100 feet in multiple colors. For example, a 14-foot cable is $3.66. I tend to buy <a href="https://www.monoprice.com/product?p_id=27483">Cat 6A</a> because it is slimmer and has better shielding, and isn’t much more expensive.</p><p>Plug one end of this cable into the Ethernet jack on the Virtual Studio device (labelled “NET” in the device picture above), and the other end connects to the internet. Plug the Ethernet cable into an Ethernet jack on your Internet modem or router (if you have both, plug it into the router). If your router has Ethernet jacks for both WAN and LAN, make sure you use a LAN jack. If you don’t have any Ethernet jacks available, you can buy an inexpensive <a href="https://www.amazon.com/s?k=ethernet+hub">Ethernet hub or switch</a>. Plug the hub/switch into your Internet modem or router (if you have both, plug it into the router), and then connect everything else through the hub/switch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/0*7_Z3cCSvyz35aBsI" /></figure><blockquote>You can use your existing internet service, as long as it has reasonably low latency/lag/jitter. The best internet service uses optical fiber (also spelled fibre). Lacking that, cable (e.g., Comcast) will work, but may have more latency. DSL can be the same or worse than cable. Satellite internet will not work, nor will any other type of wireless internet service (upcoming <a href="https://www.thalesgroup.com/en/markets/digital-identity-and-security/mobile/inspired/5G">5G wireless</a> claims to be low latency, but we’ll see how that works in practice).</blockquote><blockquote>The <strong>bandwidth</strong> (speed) of your internet connection <em>is not</em> the most important factor. Anything 4 Mbps (megabits per second) or better, for both download and upload, should be more than enough (unless there are other people using your connection at the same time). You can <a href="https://www.speedtest.net/">test your bandwidth with this website</a>, which also displays <strong><em>ping time</em></strong>.</blockquote><blockquote>The main problem is <strong>latency</strong> (audio delay, also called lag), which is the time it takes the audio to travel through the internet and get converted to digital and back. You want latency lower than 30mS (milliseconds); less is better. The <a href="https://www.speedtest.net/">ping time displayed by speed tests</a> is a rough measure of latency. Even better, on the <a href="https://app.jacktrip.org/devices">Audio Devices page of the JackTrip app</a>, when you connect your device to a server, it will display the latency range and average, and jitter (in terms of deviation) in the bottom right corner. It will look something like this:</blockquote><blockquote><strong>17.2 to 76 ms</strong>, 23 avg, 9.6 dev</blockquote><blockquote>This latency is displayed in real time and will vary.</blockquote><h3>Microphone (and other inputs)</h3><p>Most people will just need a single microphone. You may also need a special adapter cable to go from the microphone to the device.</p><h4>Microphone</h4><p>Recommended mics:<br><a href="https://www.sweetwater.com/store/detail/XM8500--behringer-xm8500-handheld-dynamic-vocal-microphone">Behringer XM8500 Mic from Sweetwater</a> — $23.00<br><a href="https://www.monoprice.com/product?p_id=600020">Good microphone from Monoprice, with an on-off switch</a> — $19.99 including shipping<br><a href="https://www.monoprice.com/product?p_id=600058">From Monoprice, good Shure mic knockoff, includes mic clip</a> — $29.99 including shipping</p><p>The mic should be placed less than a foot from the sound source (your mouth or instrument).</p><h4>Microphone adapter cable</h4><p>Most good microphones have a male XLR connector. The mic input jack on the Virtual Studio device is a 3.5mm (⅛ inch) <em>stereo</em> TRS. Note that there are two different jacks like this on the device. Make sure you use the one to the left of the RCA jacks (the one labelled “MIC” in the picture above). This cable goes from that jack to your microphone.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/607/0*-p6E2HGr3MEAwP5v" /></figure><p>Note that you must use a cable where the TRS plug is wired for stereo. That is, the mono signal from the microphone is connected to both the left and right channels of the device. Many XLR to TRS cables are instead wired for balanced mono, and <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360059469053-Sometimes-unable-to-hear-a-musician"><em>will not work</em></a>.</p><p>Recommended cable:<br><a href="https://www.sweetwater.com/store/detail/XVM110F--hosa-xvm-110f-10-foot-right-angle-1-8-inch-trs-to-xlr-female-cable">Hosa XVM-110F 10 feet, from Sweetwater</a> — $10.45, <a href="https://www.amazon.com/Hosa-XVM-110F-XLR3F-Right-Microphone/dp/B004NCUIUS/">from Amazon</a> — $9.45</p><p>Note that there are some microphones that use a 3.5mm TRS connector instead of an XLR connector. These are often designed for taking video with cameras that have a TRS microphone input. If you have one of these, you don’t need the above XLR microphone adapter cable; you can use a standard headphone extension cable (see below). You should try it out to see how it sounds, since these microphones are mainly designed for recording at a distance, rather than close-up. Again, be sure the mic does not require phantom power (also called bias voltage).</p><h4>Mic Stands and Clips</h4><p>Unless you are planning on always holding your microphone, you might want to buy a mic stand. Decide if you want a floor stand or a desk stand. You might also need a mic clip to hold your microphone on the stand.</p><p><a href="https://www.monoprice.com/search/index?keyword=mic+stand">Monoprice sells several kinds of stands and clips</a>. As does <a href="https://www.sweetwater.com/c396--Microphone_Stands">Sweetwater</a>, <a href="https://www.amazon.com/s?k=mic+stand">Amazon</a>, etc.</p><h4>Mic Extension Cable</h4><p>Your microphone should be a few inches away from the source of sound (your mouth for singing, or your instrument). It is always handy to have an extension cable for your mic, so you can place the mic wherever you want it. The extension cable for a microphone has a female XLR connector on one end, and a male XLR connector on the other.</p><p><a href="https://www.monoprice.com/product?p_id=4754">Monoprice sells good XLR extension cables</a> in many lengths. Equivalent quality cables from other vendors will be more expensive.</p><h4>Pop Filter</h4><p>If you are a singer who pops their P’s, you might want a pop filter. Of course, <a href="https://www.monoprice.com/search/index?keyword=Pop+filter">Monoprice sells them</a>, as do <a href="https://www.amazon.com/s?k=pop+filter">Amazon</a>, <a href="https://www.sweetwater.com/c394--Microphone_Pop_Filters">Sweetwater</a>, etc.</p><h4>Condenser Mics, Mixers, and Audio Interfaces</h4><p>If you have a condenser microphone you want to use, unfortunately the Virtual Studio device does not supply “<a href="https://en.wikipedia.org/wiki/Phantom_power">phantom power</a>” to it. Condenser mics are popular, but they require a source of power, which is usually supplied through the same cable as carries the microphone signal.</p><p>You can solve this problem in a number of ways:</p><ul><li>Buy a <strong>phantom power supply</strong>. Here’s one on <a href="https://www.amazon.com/Neewer-1-Channel-Microphone-Condenser-Recording/dp/B014H8AWGC/ref=sr_1_5">Amazon for $25</a>.</li><li>Get an <strong>audio interface</strong>. This is a useful device that will also let you control the volume of your microphone(s). It can also be used with other software for remote music, including Jamulus and JamKazam (and others). They cost $50 and up. More expensive ones have multiple inputs, so you can have multiple microphones, instruments, and other inputs active at the same time. You can purchase audio interfaces from <a href="https://www.sweetwater.com/shop/studio-recording/audio-interfaces/">Sweetwater</a> and <a href="https://www.amazon.com/s?k=audio+interface">Amazon</a>. You will use the analog output from the audio interface, and plug it into the Virtual Studio device.</li><li>Buy a <strong>mixer</strong>, and use it the same way as an audio interface. A mixer also lets you use multiple inputs. If the mixer has a low-latency USB digital output, it may also work with Jamulus.</li></ul><p>Here is a <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360055205273-Tested-Sound-Cards">list of sound cards and audio interfaces</a> that have been tested to work with Virtual Studio. There is also a larger list of <a href="https://jamulus.io/wiki/Sound-Devices">audio interfaces and mixers that work with Jamulus</a>, which you can also use with Virtual Studio, by using the analog outputs.</p><p>You will plug your microphone into the phantom power supply, audio interface, or mixer, which will supply power to it (you will have to turn on a switch, usually labelled “phantom power”). Then take the analog output from that box and run it into the mic input on the Virtual Studio device.</p><p>If you have a USB microphone that also has an analog output (in addition to the USB) you can probably use it as well. You have to plug in the USB cable to supply power to the mic, but you will use the analog output (typically a 3.5mm TRS connection) to connect to the device.</p><h3>Headphones</h3><p>You should use headphones when you are doing music remotely. If you use speakers, the sound will get picked up by your microphone and cause feedback, echo and other problems. Use wired headphones only (no wireless or Bluetooth, which will cause latency and jitter).</p><p>It is recommended that you use headphones that do not also have a microphone (often called a <em>headset</em>), as those have a different kind of connector (TRRS instead of TRS, with two rings instead of one). Alternatively, you can get a <a href="https://www.amazon.com/UGREEN-Headphone-Splitter-Computer-Smartphone/dp/B073ZDDTH2/ref=sr_1_3">splitter adapter</a> and use only the headphone plug, ignoring the microphone plug.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/0*zt_jNzey-TGyavte" /></figure><p>Making this even more confusing, there are two standards for wiring TRRS connectors:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/621/0*MjlJYcmBfiuDD7r4" /></figure><p>If you don’t know which one you have, <a href="https://www.amazon.com/Universal-3-5mm-Earphone-Converter-Adapter/dp/B07Q8GLYW3/ref=sr_1_1_sspa">you can buy a universal adapter</a>. But the easiest solution is to use headphones without a microphone.</p><p>If you need to buy headphones, here are some recommendations:<br><a href="https://www.amazon.com/gp/product/B00001P4ZH/ref=ppx_yo_dt_b_asin_title_o03_s01">Koss Porta Pro wired headphones</a> — $34.99<br><a href="https://www.monoprice.com/category/audio-video/headphones">Lots of headphones on Monoprice</a> — $16.99 and up</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/615/0*h2nigDhDUqP2m9HA" /></figure><p>If you already own a set of headphones that meet the guidelines in the previous paragraphs, you can use them. Older headphones often have a large ¼ inch (6.35mm) plug, instead of the smaller ⅛ inch (3.5mm) plug. If so, you can buy a ⅛ inch male TRS to ¼ inch female TRS adapter:<br><a href="https://www.monoprice.com/product?p_id=7135">From Monoprice</a> — $0.51<br><a href="https://www.amazon.com/JBingGG-Stereo-Female-Adapter-Converter/dp/B073Q3Z781/ref=sr_1_10">From Amazon</a> — $6.99</p><p>You can also use earbuds, as long as they are wired (and either don’t have a microphone, or you use a splitter adapter cable).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/651/0*GrzF0jYahGRrp54-" /></figure><h4>Headphone adapter cable</h4><p>You will also need a short adapter cable to connect your headphones into the Virtual Studio device. The device audio output is two RCA jacks. Your headphones should use a 3.5mm (⅛ inch) stereo TRS phone plug, so you will need a short adapter cable that looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/359/0*vudf-9yNannepRAe" /></figure><p>Assuming you have (or buy) headphones with a 3.5mm (⅛ inch) TRS plug, recommended adapters are:<br>Hosa YMR-197 Stereo 3.5mm TRS Female to dual RCA Male, from <a href="https://www.sweetwater.com/store/detail/YMR197--hosa-ymr-197-stereo-breakout-3.5mm-trsf-to-dual-rca-6-inch">Sweetwater</a> — $4.95, from <a href="https://www.amazon.com/Hosa-YMR-197-Stereo-Breakout-Cable/dp/B000068O5F/ref=sr_1_1">Amazon</a> — $4.95<br><a href="https://www.monoprice.com/product?p_id=5612">Monoprice 3.5mm Stereo Female to 2x RCA</a> — $2.22</p><h4>Headphone extension cable</h4><p>Headphones almost always come with a built-in cable around 3 to 6 feet long, but if you want to get further away from the device, you can buy an extension cable, in your desired length.<br><a href="https://www.monoprice.com/product?p_id=648">From Monoprice</a> — $0.83 and up<br><a href="https://www.amazon.com/AmazonBasics-3-5mm-Female-Stereo-Audio/dp/B01CNAUYBY/ref=sr_1_3">From Amazon</a> — $6.98 and up</p><h4>Headphone Amplifier</h4><p>The audio output from the Virtual Studio device is not very powerful and can distort if you try to make it much louder. Some people will want to buy a headphone amplifier. Most headphone amplifiers can drive more than one set of headphones, which is useful if more than one person will be singing or playing over a single Virtual Studio device.<br><a href="https://www.amazon.com/Behringer-HA400-Ultra-Compact-4-Channel-Headphone/dp/B000KIPT30/ref=sr_1_8">Behringer HA400 from Amazon</a> — $23.99, <a href="https://www.sweetwater.com/store/detail/HA400--behringer-microamp-ha400-4-ch-headphone-amplifier">or Sweetwater</a> — $23.99<br><a href="https://www.monoprice.com/product?p_id=615220">Monoprice 4-channel headphone amplifier</a> — $31.99</p><p>You may need to get an <a href="https://www.monoprice.com/product?p_id=5597">additional cable</a> for this, and probably some <a href="https://www.monoprice.com/product?p_id=7139">¼ inch to ⅛ inch TRS adapters</a>. For some reason headphone amplifiers almost always use ¼ inch (6.35mm) connections.</p><h3>Purchasing Checklist</h3><p>What you need to do to get all the hardware you need.</p><ul><li>Acquire a Virtual Studio device.</li><li>Find your internet router and modem (they may be combined). Make sure you have an Ethernet jack that is not occupied by anything you need. If you don’t, you may need to purchase an Ethernet hub or switch.</li><li>Decide where you will put the Virtual Studio device. Figure out the lengths of the cables you will need, including the Ethernet, microphone, and headphone cables.</li><li>Read this document to figure out what else you need to buy, and buy it. Some things will be purchased by everyone in your group, so if possible get together and buy in bulk.</li></ul><h4>Sweetwater Bundle</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LfDp96XA_w56bzjm" /></figure><p>Sweetwater is selling an accessory kit, called the “<a href="https://www.sweetwater.com/store/detail/LiveOnlineBun--behringer-live-online-essentials-bundle">Behringer Live Online Essentials Bundle</a>” that includes the microphone (#2), mic adapter cable (#1), headphone adapter cable (#3), and ethernet cable (#6), which is everything in the image above except for the Virtual Studio device (#5) and its power supply (#4). This is convenient, but the price is the same as if you bought them separately. And you will still need to supply headphones.</p><h3>Virtual Studio Cloud Service</h3><p>Playing music together happens through a shared server. In order to keep latency low, you need to use a server that is as close to your group as possible.</p><p>The Virtual Studio cloud service provides virtual servers that allow a group of people to connect over the internet and make music together. Each group of people will need (at least) one server, which is typically <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360053416674-Managing-Audio-Servers">set up and controlled</a> by the leader of the group. If you want to create a new group of people, you can connect to an additional server. Here’s the list of the <a href="https://help.jacktrip.org/hc/en-us/articles/360055468393-Geographical-Regions-for-Managed-Audio-Servers">geographical regions that have servers</a>. It is also possible (but more difficult) to <a href="https://help.jacktrip.org/hc/en-us/articles/360056926013-Creating-Unmanaged-Servers">construct your own servers</a>.</p><p>During the beta period, these servers are free. After that, they will cost a <a href="https://jacktrip.org/pricing.html">small amount of money</a> per hour. You should get into the habit of disconnecting from the server after you are done using it, so additional costs will not be incurred in the future.</p><p>You will use the <a href="https://app.jacktrip.org/">Virtual Studio web app</a> to connect to a server and control your Virtual Studio device.</p><h3>Setup Checklist</h3><p>The actual setup is pretty straightforward. This checklist focuses on extra things, including potential problems. The term “device” refers to the Virtual Studio device. The device is managed by a web app, both to set it up, and to control it.</p><ul><li>Open a web browser, which can be on any computer, including tablets and even smartphones, but it must be connected to the same local area network (LAN) your device is on. This computer (or tablet or phone) can connect via WiFi or wired Ethernet; although it can be connected wirelessly, you cannot connect using cellular data (e.g., on a phone or tablet), as that is not the same network.</li><li>If you have not done this already, create a login on the <a href="https://app.jacktrip.org/">Virtual Studio online app website</a>, and log in. This web app is used to control your device and connect it to a remote group server. When you see the page asking you to log in, scroll down until you see “Don’t have an account? Sign up”. If you haven’t yet finished setting up your device, after you sign up you will see a warning that you don’t have any active devices.</li><li>Have the chorus/band/group leader invite you to the group server, using the email address that you used to sign up in the previous step. That server will show up in the web app when it is available to you and running.</li><li>Check to make sure there is nothing loose or rattling around inside the device case. If there is, see the instructions in the “Virtual Studio device” section, above.</li><li>Hook up the microphone, headphones, internet, and power to the device.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rwKEW-tSDpuUz6xf" /></figure><ul><li>The very first time you power on the device, it can take 1–2 minutes to update the software on the Micro SD card. After this is done, you may need to cycle power to the device to get it to run properly. There are two LEDs on the side of the device opposite the Ethernet connection, one green and one red (these are not the LEDs on the Ethernet connection itself). The red light indicates that power is on; if it flashes there is a problem with the power supply. The green light blinks to show activity. Wait until the green light has stopped blinking and stays dark for a while (30 seconds?) before powering the device off and then back on.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/536/0*1OGcTWZyNeTBVcbW" /></figure><ul><li>Now look at the Ethernet connector on the device and make sure the green light on it (below the connector) is blinking, showing that it is connected to the internet.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hhfCQ7Cvx35RaGFW" /></figure><ul><li>Open a browser window on your computer (or tablet or phone) and type in the following URL exactly as written: <a href="http://jacktrip.local/">http://jacktrip.local</a> (if you are reading this document online, you can just click on this link). If you get an error message, it is probably because your device and browser are not on the same local network.</li><li>At this point it will probably tell you that you have no audio devices registered to this account, or it might first ask you to log on, or to create a new login. Do what you need to do to open up the New Device Registration dialog. If you get an error, see <a href="https://help.jacktrip.org/hc/en-us/articles/360057094613">Troubleshooting http://jacktrip.local</a> for help.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*XQ_u4szgFYB7V8J3" /></figure><ul><li>You should change the name to something unique that identifies you. Then click the “REGISTER DEVICE” button.</li><li>You should now see the control panel for your device.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2mIBf226ufxK7NX0" /></figure><h3>Test your Device</h3><p>To test your device, you need to connect to a server. Probably the easiest (and most fun) way to do this is to have everyone in your group connect to your group server. That way you can get everyone in your group connected, and help each other if you run into any problems. To do this, whoever is in charge with your group will have to start the server.</p><ul><li>If you need to get back to the control panel for your device, in a browser window open <a href="https://app.jacktrip.org/devices">https://app.jacktrip.org/devices</a>. Make sure your device is powered and running.</li><li>Turn on your device. Each time you power on the device, it may take a minute, as it is checking the software for updates. Make sure the device gets powered off regularly, so it can do this.</li><li>In the Select Server input of the control panel, find the name of your group server and select it. Make sure it says “Ready”. If not, talk to your group leader. Then click the green Connect button. You should now be connected to that server.</li><li>Once you are connected to the group server, in the control panel you will normally want to have the Limiter turned on and the Compressor turned off.</li><li>Unmute both the “Input Volume” and “Output Volume” icons and move both volume sliders to 100%. With your headphones on, talk into the microphone and see if you can hear it. If you are not sure, you can turn on “Boost” for the Output Volume. Adding some Reverb can also help you hear your voice.</li><li>If you hear distortion in your voice, turn down the “Input Volume”. There is a short delay each time you adjust the volume.</li><li>If you don’t have enough volume in your headphones, you might want to purchase a headphone amplifier (discussed above).</li></ul><p>You should now be able to hear your audio on the device. Note that you are hearing your voice via the remote server, so there will be some delay, but hopefully not very much.</p><p>If you are unable to hear audio or your device control panel shows 100% packet loss, it may be caused by your Internet router blocking traffic from the device (see <a href="https://help.jacktrip.org/hc/en-us/articles/360057149533">Troubleshooting Firewall Ports</a>). You should also double-check all the connections and ensure that your microphone and headphones are not plugged into the wrong ports.</p><p>When done testing, click the “DISCONNECT FROM SERVER” button to disconnect your device from the remote server. If you are the person in charge of the server, you should also shut down the server.</p><p>For more information, see <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360053538614-Getting-Started-with-a-Virtual-Studio-Device">Getting Started with a Virtual Studio Device</a>.</p><h3>Creating your own Server</h3><p>Instead of connecting to the group server for testing, you can create your own server. This is also useful if you are in a group that has multiple sections, and you want to have practice sessions for your small group. Anyone can create and use their own server. Just remember that when server time starts costing money, the creator of the server will have to pay a (relatively small) amount for that use.</p><p>See <a href="https://jacktrip.zendesk.com/hc/en-us/articles/360053416674-Managing-Audio-Servers">https://jacktrip.zendesk.com/hc/en-us/articles/360053416674-Managing-Audio-Servers</a> for detailed instructions on setting up a new server.</p><h3>Video connection</h3><p>If you want to see the other people you are playing with, you can use a conferencing program such as <a href="https://zoom.us/">Zoom</a>, <a href="https://workspace.google.com/products/meet/">Google Meet</a>, <a href="https://duo.google.com/about/">Google Duo</a>, <a href="https://www.skype.com/en/">Skype</a>, etc. Note that these programs will have more latency (delay) than the Virtual Studio, so I would recommend turning off the audio on your conference app by having everyone mute their microphone. Also, there will likely be a delay (up to a full second!) between the audio signal (going through Virtual Studio) and the video from the conferencing app, so trying to conduct a group by waving your hands just won’t work.</p><h3>Building a Virtual Studio Device</h3><p>If you cannot find the Virtual Studio device for sale, you can <a href="https://jacktrip.zendesk.com/hc/en-us/sections/360009752894-Building-Your-Own-Device">build it yourself</a>. However, it requires quite a bit of technical skill. If you have a friend who is technical, they can probably build it.</p><p>You can buy everything you need to build the <a href="https://www.hifiberry.com/shop/bundles/hifiberry-dac-bundle-4/">Virtual Studio Device from HiFiBerry</a>. This is what you need to select:</p><ul><li>HiFiBerry DAC+ ADC Pro — $64.90</li><li>Steel case for HiFiBerry Dac+/Adc, Pi 4 — $22.90</li><li>Raspberry Pi 4B 2GB — $44.90</li><li>No heatsink (unless you want it, which won’t hurt)</li><li>SD (Micro SD) card 16GB — $12.90</li><li>If you are building your own device, you need a Micro SD card reader to load software on the Micro SD card (see below) — $6.90</li><li>You can add the power supply if you need to buy one anyway — $12.90</li></ul><p>The last two items are optional if you already have them. They are not included if you buy the built device from Amazon. Without the last two items, the parts cost $145.60 (plus shipping). So you aren’t saving much money building it yourself this way. I have written an article that details how to build a low-cost Virtual Studio device, which I will be publishing soon.</p><p>Note that many of these things can be purchased elsewhere for less money. For example, you can get the same Raspberry Pi for $35 from <a href="https://www.adafruit.com/product/4292">Adafruit</a>, <a href="https://www.digikey.com/en/products/detail/raspberry-pi-(trading)-ltd/RASPBERRY%2520PI%25204B%2F2GB/10258782">Digi-Key</a>, or others (slightly more from <a href="https://www.amazon.com/Raspberry-Model-2019-Quad-Bluetooth/dp/B07TD42S27/">Amazon</a>). Same thing for the <a href="https://www.amazon.com/Sandisk-Ultra-Micro-UHS-I-Adapter/dp/B073K14CVB/ref=sr_1_3">Micro SD card</a> and <a href="https://www.adafruit.com/product/4298">power supply</a>.</p><p>If you are building your own Virtual Studio device, you will need to load software onto the Micro SD card from your computer. To do this, you will need a card reader that plugs into a USB port on your computer. If you have a newer computer it might use USB-C ports (which take the left-most plug, below) instead of the traditional USB-A ports (second plug, below). You are only going to need to do this once, so you can also borrow one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/265/0*WA_jM7wQ_Xvp7vnt" /></figure><p>Here is an <a href="https://www.amazon.com/SmartQ-MicroSDXC-MicroSDHC-Windows-Android/dp/B07ZHNGM3G/ref=sr_1_11">SD card reader from Amazon</a> ($7.99), which works in both USB-A and USB-C ports, and can read (and write) both regular (fullsize) SD cards and Micro SD cards. Alternatively, f you already have a Micro SD card reader that has the wrong connector for your computer, you can buy an <a href="https://www.monoprice.com/product?p_id=13507">adapter from Monoprice</a>. If you have a regular (fullsize) SD card reader, there are <a href="https://www.amazon.com/SanDisk-microSD-Memory-Adapter-MICROSD-ADAPTER/dp/B0047WZOOO/ref=asc_df_B0047WZOOO/">adapters for Micro SD cards</a> that let them fit in a regular SD card reader.</p><p><a href="https://jacktrip.zendesk.com/hc/en-us/articles/360055205313">Follow these instructions</a> to load the software onto the Micro SD card. You can do it from any computer, along with the card reader.</p><h3>Further Reading</h3><p><a href="https://app.jacktrip.org/">Virtual Studio online app</a>. Create a login here. Once you do that and sign in, you can create a server or connect to an existing server.</p><p><a href="https://www.jacktrip.org/studio.html">JackTrip Virtual Studio overview</a>.</p><p><a href="https://jacktrip.zendesk.com/hc/en-us/categories/360004519513-User-Guide-Virtual-Studio">JackTrip documentation for Virtual Studio</a>.</p><p><a href="https://www.jacktrip.org/">JackTrip website</a>.</p><p><a href="https://www.jacktrip.org/technology.html">Information about latency, lag, and jitter</a>.</p><p><a href="https://groups.google.com/forum/#!forum/jacktrip-users">JackTrip users email list</a>.</p><p><a href="https://jacktripcollaboration.slack.com/">JackTrip Slack group</a>. Here’s the <a href="https://join.slack.com/t/jacktripcollaboration/shared_invite/zt-g3iz2nkh-d9tQeOZItS30SZUELaXf1A">link to join the group</a>.</p><p>If you are confused about connector types (like TRS, XLR, etc.) <a href="https://www.sweetwater.com/insync/cable-buying-guide/">Sweetwater has a nice guide</a> to the common ones. Also see <a href="https://www.boxcast.com/blog/balanced-vs.-unbalanced-audio-whats-the-difference?fbclid=IwAR0pWOyLDs8oN3AWr8SfbSSs12I4EkNY-I7H0UwTEKVJioL8AfutmSg6sJw">this article</a> about balanced versus unbalanced cables.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6a9fbea56f08" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Canceling Amazon Prime]]></title>
            <link>https://wmleler1.medium.com/canceling-amazon-prime-d0355bde666c?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/d0355bde666c</guid>
            <category><![CDATA[retail]]></category>
            <category><![CDATA[compétition]]></category>
            <category><![CDATA[mail-order]]></category>
            <category><![CDATA[customer-service]]></category>
            <category><![CDATA[monopolistic-competition]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Sun, 17 May 2020 03:07:04 GMT</pubDate>
            <atom:updated>2021-01-31T22:02:09.900Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-sa/4.0/</cc:license>
            <content:encoded><![CDATA[<p>Here are the things that led me to cancel Amazon Prime, including reasons you should think about dropping it too. I’m not trying to single out Amazon, this is primarily a cost-benefit analysis.</p><p>Full disclosures: I’ve had various relationships with Amazon for a long time. I buy a lot of uncommon stuff that is hard to find, so I order things from Amazon frequently. In 2019 I averaged more than one order a week from them, typically containing multiple items. I also watch videos and read ebooks from Amazon Prime.</p><p>In addition, I used to be the CEO of a company that sold things online. We built and ran e-commerce sites for large media companies, including HBO, Sony, Paramount, Tribune Media, Douglas Adams, and many others. We created, inventoried, and sold merchandise, managed advertising campaigns, and shipped to customers. We also became one of the first third-party vendors for Amazon. In that early era of online e-commerce, we used data heavily to figure out what worked and what didn’t. So I have some insight into this kind of business and how they operate.</p><h4>Amazon Prime</h4><p>I joined Amazon Prime (AP) when it was first offered because it<a href="https://www.nerdwallet.com/blog/shopping/amazon-prime-benefits-cost-worth/"> made sense back then</a>. I ordered stuff often enough that I easily saved the cost of AP. When they added videos, that made it an even better deal. Ordering most things from Amazon also made sense because it saved time — I only had to look in one place because their prices were good.</p><p>Of course, over time little cracks appeared in this logic. The first thing I noticed was that as Amazon became more popular their prices started to rise. Even though I would often first look on Amazon for a product, I started looking in other places too, to make sure. So I was no longer looking in only one place. What really surprised me was that often I could find common things in a local (brick and mortar) store for less money than on Amazon.</p><p>Even so, that didn’t stop me from shopping on Amazon because it was easier and still saved time, especially for the unusual things.</p><p>In addition, the world started to change. I found that as streaming services proliferated there were fewer and fewer videos to watch on Amazon Prime. Libraries started offering ebooks for free. I found I didn’t use those extra benefits anymore. So the cost-benefit analysis became mostly about shipping costs and convenience.</p><p>Unfortunately, Amazon started to <em>nickel and dime</em> (you know, like what airlines do). First, the cost of AP kept rising. Even worse, Amazon kept finding ways to make it less of a benefit. For example, for some time they stopped giving free shipping at all for inexpensive things, typically those that cost around $5 or less. You either had to pay for shipping (even though I was already paying increasing amounts of money for AP to get “free” shipping) or you had to wait and order those small items at the same time you ordered more expensive items, so they could be shipped together. That was a <em>huge crack</em> in both primary advantages of AP — cost and convenience.</p><p><em>This often happens when companies grow so large and successful that they become more interested in making as much money as possible, rather than taking care of their customers. Not just airlines, but also US car companies, which is what allowed foreign (mostly Asian and European) car companies to become dominant (even my favorite US car brand, Chrysler/Plymouth/Dodge/Jeep, is now owned by Fiat).</em></p><h4>Delivery Problems</h4><p>Next, even though AP promised two-day shipping, they started to break that promise. Some items arrived days, or even a week or more late, for no particular reason. Note that this started happening months before the coronavirus caused disruptions and delays. But the pandemic definitely made it more common. In fact, nothing I’ve ordered in the last month or so has actually arrived when Amazon said it would, <em>even when they said it would arrive in 3 weeks rather than the 2 days AP promised</em>.</p><p>Even worse, some things <em>never arrived</em>. Here are some examples:</p><p>I ordered four items of clothing. When the box arrived, there was only one of them in the box. The other three were missing. Someone forgot to put them in the box, or perhaps stole them. That’s when I noticed that there was no way to contact Amazon customer service. There was an automated way to do a return, but you can’t return something you never received! Amazon had no option covering not receiving a package, even though I knew that shipping mistakes and lost packages are not particularly uncommon (from my experience running an e-commerce company).</p><p>Amazon’s only contact point for customer service is their chat system. But their chat system is a robot, not a real person. I tried every way I could to explain what had happened, but the chat robot never understood. I tried asking to speak to a real person, but it ignored me. I spent hours trying to get the chat system to help but to no avail. It would just give me answers that had nothing to do with my problem.</p><p>Another order only had two things in it. They were supposed to arrive the same day, in separate packages. On the scheduled day, one package arrived just fine. The other package was not delivered. When I tried to track it, Amazon said that they were unable to deliver the package because there was something stopping them from accessing my front door. There was someone home the whole time. Plus they <em>were</em> able to deliver the other package the same day.</p><p>The Amazon tracking page said that they would try to deliver the package again. Weeks went by. Amazon continued to claim they would deliver it right away. Again, no way to contact Amazon, and no way to fix the problem with their hopeless automated chat system.</p><p>Another order was for a single item from a third-party vendor on Amazon. Watching the Amazon tracker, it said it was being shipped via the USPS. Soon, it showed that it was in transit and eventually said the package would be delivered that day. But when I went to the USPS website with the tracking number, I discovered two things:</p><ol><li>It was not actually shipped by USPS. Amazon shipped it themselves, and they were responsible for all the shipping other than the actual delivery. Instead, they would hand it off to a post office near me, and the USPS would deliver it.</li><li>The item had not actually shipped yet. It was still in the Amazon warehouse. The tracking information from Amazon was a lie. Lucky for me, I knew how to get to the actual tracking information.</li></ol><p>So while Amazon’s tracking info made it look like the shipping problem was caused by the Post Office, it was really their problem.</p><p>Not surprisingly, the item never arrived that day. That night, the Amazon tracking info suddenly changed to saying that the item had not shipped yet.</p><p>I tried Amazon’s infernal chatbot one last time, and something completely different happened. It immediately asked me if I was asking about that particular order, and then offered to let me talk to a real person, which I did. And they were able to fix some of my issues! It was like night and day.</p><p>I’m guessing (but pretty sure) that the reason I was able to talk to a real person was because that package was from a third-party vendor, and the Amazon chatbot had a completely different script for them. Ironically, the only problem they were not able to fix was the package from the third-party vendor.</p><p>I’ve had plenty of other examples since then (including more packages where the Amazon tracking page contained incorrect information). Thinking about it I realized that I was spending more time tracking down orders than the time I had saved by buying them from a single vendor. When I talked to friends about this, many had similar experiences, but they chalked it up to the pandemic disrupting shipping. But that doesn’t explain why Amazon’s tracking information was often wrong.</p><p>Even more telling, I had ordered several items from vendors other than Amazon, including Costco, eBay, and Monoprice. During the same time when every order from Amazon was delivered late (or not at all), I never had any problems with any other vendor. And none of them gave me bad tracking info. I received their packages when they said I would.</p><h4>Lock In</h4><p>I was paying $119 a year for AP shipping that was far worse than (often free) shipping from these other vendors. The worst part of this is that once you pay all that money for “free shipping” it tends to <em>lock you in</em> to using that vendor, because you’ve already paid for it. And once you are locked into Amazon, they have less and less incentive to actually do a good job for you. The bigger they get, the less you mean to them as a customer.</p><p>But AP had a much more insidious effect. Paying for AP also meant that I was doing less shopping at local businesses. This despite that I had found that local businesses were often able to compete on price with companies like Amazon.</p><p>The question for me became, <strong>how much are people willing to pay to live in a nice, vibrant city</strong>? Most people are willing to pay a lot more to live in a really great city. And there is strong evidence that communities with thriving local businesses have lower rates of crime and poverty, and higher rates of giving, volunteering, and voting. But the pandemic and its shutdowns and economic damage are threatening to kill many (if not most) local businesses.</p><figure><img alt="CC BY-SA 2.0" src="https://cdn-images-1.medium.com/max/1024/1*MhA4FhNl3S4tQ_5JNwpTaw.jpeg" /><figcaption><a href="https://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a></figcaption></figure><p>Who wants to live in a place where most of the local retail businesses are boarded up? It makes good financial sense to buy at local businesses to keep them alive. And as mentioned, in many cases you won’t have to pay more, and you also have the opportunity to build a beneficial relationship with a small business owner.</p><p>For example, where I live, a local small business owner solved the problem of not being allowed to have customers in her store by setting it up so that people could contact her over FaceTime. She then walks people around the store virtually (in better times, she would have been doing that in person anyway). Then when you are done shopping, she will either ship the items to you or you can drive by and pick them up at the curb.</p><p>So I decided to find ways to do more local shopping, and even if I need something I cannot find locally, I will only use Amazon (or similar companies) as a last resort. By canceling AP, I will not be locked into a single vendor anymore. After all, the time spent buying from local shops probably won’t take more time than I’ve been spending fighting Amazon’s shipping problems, and it will be so much more enjoyable to interact with actual owners of small businesses in my local community.</p><h4>Bottom Line</h4><ul><li>AP tends to lock you into buying from one vendor, and that creates a monopoly, which invariably reduces your choices and raises prices.</li><li>AP may have once been a good deal. Make sure it is still working for you. Amazon has already shown that it will charge more and provide fewer benefits over time.</li><li>Buy locally. If your local businesses die, you will become more dependent on large, impersonal monopolies, and your hometown will suffer. Because of the coronavirus, many local shops now have ways that you can shop online or by phone, and it will be easier for you to get to talk to a real person.</li></ul><p>Give it a try!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d0355bde666c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding Encryption to a Fast Database]]></title>
            <link>https://wmleler1.medium.com/adding-encryption-to-a-fast-database-63ca1e14edc4?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/63ca1e14edc4</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[key-value-database]]></category>
            <category><![CDATA[encryption]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Mon, 23 Mar 2020 23:12:58 GMT</pubDate>
            <atom:updated>2020-03-27T16:54:22.110Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="Dgraph Labs" src="https://cdn-images-1.medium.com/max/400/1*ZJ500MFNXqZM5VXw2DBsbw.png" /></figure><p>This article will be of particular interest to people who are curious about how powerful encryption can be implemented in high performance systems. It is also for people who just want to know a bit more about how strong encryption works and how all the pieces fit together.</p><h3>Introduction</h3><p><strong>Making a system secure is very difficult</strong>. <a href="https://www.csoonline.com/article/2130877/the-biggest-data-breaches-of-the-21st-century.html">Data breaches of large and widely used systems</a> — for example, at Adobe, Anthem, eBay, Equifax, Home Depot, JP Morgan Chase, Marriott, Sony, Target, Uber, VeriSign, Yahoo, the US Office of Personnel Management, and even good security companies like RSA Security — have cost billions of dollars and compromised the privacy or identity of over a billion users.</p><p>Everyone says they want more secure systems, but people don’t like using systems that are slow or hard to use, and making a system more secure can add delays and reduce convenience. It is clearly bad when people avoid using a system that is secure, and instead choose a system that is less safe but faster or easier to use.</p><p>Because databases store the data that we most need to protect, they are a major piece of the security puzzle. How can we add strong encryption to a database without unduly compromising speed or usability? Looking at how various companies have done this can help.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/222/1*2VI70ILXcsI1blW0Gr8KvA.png" /></figure><h3>Badger, a Fast DB</h3><p>This article examines how the team at <a href="https://dgraph.io/">Dgraph Labs</a> added <a href="https://blog.dgraph.io/post/encryption-at-rest-dgraph-badger/">data encryption to Badger</a>, an extremely fast and reliable open-source database. <a href="https://github.com/dgraph-io/badger#badgerdb------">Badger</a> has over 7.3K stars on Github and is used in over 850 <a href="https://github.com/dgraph-io/badger#other-projects-using-badger">projects</a><strong>,</strong> including Uber’s <a href="https://github.com/jaegertracing/jaeger">Jaeger</a> and <a href="https://github.com/ipfs/go-ipfs">IPFS</a>. Most notable is <a href="https://www.usenetexpress.com/">UsenetExpress</a>, which stores petabytes of data using Badger.</p><p>Badger is a <a href="https://en.wikipedia.org/wiki/Key-value_database">key-value database</a> (KVDB). A KVDB stores data in associative arrays (also variously called objects, dictionaries, maps, or hash tables).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/226/1*oOthGKeVV2adgMHjNiE83A.png" /><figcaption>associative array</figcaption></figure><p>KVDBs have become popular because they are one of the simplest and fastest kind of databases, and they are easy to learn because they use a data structure that is common in most programming languages.</p><p>KVDBs are well suited for use in cloud computing, and Badger is particularly fast for cloud use because it is <a href="https://blog.dgraph.io/post/badger/">heavily optimized for typical cloud hardware</a>, especially SSD storage. Badger provides <a href="https://blog.dgraph.io/post/badger-over-rocksdb-in-dgraph/">great performance</a> on such hardware, compared to other popular KVDBs.</p><p>The challenge for the team was to figure out how to implement encryption without compromise. We knew that this should be possible, because companies were able to (eventually) figure out how to add encryption to http (creating https) without making it noticeably slower for the end user.</p><p>As we shall see, Badger’s advanced implementation positively affected how encryption was added to it.</p><h4>Implementation of Badger</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/193/1*0jq7labjZMnttlyn8FPfnQ.jpeg" /><figcaption>The Go Gopher</figcaption></figure><p>Even without encryption, the implementation of Badger makes it safer and less prone to errors that could compromise security. It is written in the <a href="https://en.wikipedia.org/wiki/Go_(programming_language)">Go language</a>, which was developed by a small team at Google that included <a href="https://en.wikipedia.org/wiki/Ken_Thompson">Ken Thompson</a> (<a href="https://www.unixmen.com/ken-thompson-unix-systems-father/">UNIX</a>, <a href="https://en.wikipedia.org/wiki/Thompson%27s_construction">regular expressions</a>, <a href="https://news.ycombinator.com/item?id=12617363">Plan 9</a>, <a href="http://doc.cat-v.org/bell_labs/utf-8_history">UTF-8</a>). The goal of Go was to improve the C language, by adding memory safety, automatic garbage collection, safe concurrency, and multiprocessing across networked computers. Badger has quickly become the most active KVDB written in Go.</p><p>Badger is designed to be used inside of other projects. It is <strong>implemented as an embeddable library</strong>, rather than as a separate service. This increases both security and speed. And as mentioned before, <a href="https://github.com/dgraph-io/badger">Badger is open source</a>, so it can be <a href="https://medium.com/@chaomengting/is-open-source-software-more-reliable-or-secure-than-closed-source-software-5470732d7b90">reviewed to find unsafe code</a> or even modified to meet project needs.</p><p>Badger is also very reliable. It guarantees serializable snapshot isolation (SSI) by running concurrent <a href="https://blog.dgraph.io/post/badger-txn/">ACID</a> transactions using multiversion concurrency control (<a href="https://en.wikipedia.org/wiki/Multiversion_concurrency_control">MVCC</a>). Badger is resilient in the face of process, filesystem, and even hardware crashes.</p><h4>Separating keys from values</h4><p>An advanced feature of Badger’s implementation is splitting up the key-value pairs and storing the values separately from the keys. Keys are typically short strings, so storing them together in one place makes searching for a key significantly faster. Keys typically don’t change as often as values, so more extensive optimization of the key files (including the hash tables used to look up a key) can be done to improve performance even more.</p><p>On the other hand, values are typically larger and change more often than keys. For example, a value can be an entire document that is updated as the document is edited. Multiple values are stored in a value log file (vlog). Associated with each key is a <strong>pointer to its value</strong>, consisting of the vlog file id, the offset of the value in the file, and the size of the value. Note that as an optimization, values smaller than a user specified size (default 32 bytes) are stored with their associated keys rather than in a vlog file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*6jPC95AV0gRFym47NNYplA.png" /><figcaption>key-value file and vlog file</figcaption></figure><p>Assuming 16 bytes per key and 16 bytes per value pointer, <strong>a single 64MB file can store two million key-value pairs</strong>. This is small enough to fit inside the RAM of virtually any computer, which means that often a key search can be done in high-speed memory, which can be orders of magnitude faster than searching secondary storage.</p><h3>Layering Badger</h3><p>In addition to being used by itself as a database, Badger can be used to implement more sophisticated databases. In particular, Dgraph Labs <a href="https://blog.dgraph.io/post/badger-over-rocksdb-in-dgraph/">created Badger</a> specifically for use in its flagship product, <a href="https://dgraph.io/">Dgraph</a>, the first native GraphQL database. Dgraph is open source, and is highly scalable to a large number of servers either on fixed computers or in the cloud.</p><figure><img alt="Layering" src="https://cdn-images-1.medium.com/max/280/1*SPOFpyIyT8MWydZBkgkY6g.png" /></figure><p>Layering Dgraph on top of Badger provides significant benefits, in particular <a href="https://en.wikipedia.org/wiki/Separation_of_concerns">separation of concerns</a>. Dgraph uses Badger to store the user’s data, so Dgraph is not concerned with data storage at all (including encryption of stored data). Because Badger is a smaller, independent system, new features like encryption can be built, tested, and verified more easily and with more confidence. Badger transparently provides encryption to Dgraph, or to any other system that uses Badger to store data.</p><p>This is similar to the <a href="https://en.wikipedia.org/wiki/Internet_protocol_suite">Internet Protocol Suite</a>, which provides high level protocols like TCP on top of lower level protocols like IP. This allows other high level protocols (e.g. UDP, DCCP, SCCP, RSVP) to be built on top of IP. When improvements are made to IP (such as IPv4 to <a href="https://en.wikipedia.org/wiki/IPv6">IPv6</a>), higher level protocols can all take advantage of them easily.</p><h3>Advanced Encryption Standard</h3><p>One of the easiest decisions to make when adding encryption to Badger was picking the highly regarded <a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES</a> encryption algorithm, standardized by the <a href="https://en.wikipedia.org/wiki/National_Institute_of_Standards_and_Technology">US NIST</a> and used by MongoDB, SQLite, and many other databases and systems. AES has become an industry standard as it is the most <em>secure and widely used</em> algorithm for encrypting data. Wide use is critical for encryption standards as they help potential security flaws get found and fixed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/391/1*Ap4z69rFUG6wT9vfzLEi1A.png" /></figure><p>AES is symmetric; the same encryption key is used for both encrypting and decrypting data. Badger supports <a href="https://www.cryptomathic.com/news-events/blog/symmetric-cryptography-and-key-management-considerations-on-key-exhaustion-rotation-and-security-models">key rotation</a> to further secure access to data. This allows Badger to be used in systems that need to meet the various data protection regulations and requirements, including GDPR, HIPAA, and PCI DSS.</p><h3>Key Rotation</h3><p>To encrypt and decrypt data requires an encryption key. AES keys come in three sizes: 128, 192, and 256 bits. Which size you use is actually <a href="https://proprivacy.com/guides/aes-encryption">not very important</a>, as a brute force crack of a 128-bit key would take the fastest computer in the world over a hundred-quadrillion (10 to the 17th power) years. Even if you could get 10 million supercomputers to work together to do the crack, it would still take longer than the current age of the universe.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*my7E3n1gc7IlyMD8Ti_eUA.jpeg" /><figcaption>Physical security is important</figcaption></figure><p>Much more important is maintaining the security of the key to avoid <a href="https://en.wikipedia.org/wiki/Information_leakage">key leak</a>. Obviously, encryption keys must be stored securely by the user and should not be easy to guess. However, there are other sources of key leak. For example, “side channel” attacks have <a href="https://resources.fox-it.com/rs/170-CAK-271/images/Tempest_attacks_against_AES.pdf">demonstrated</a> that it is possible to crack even the most secure (256-bit) AES keys in a short period of time by measuring electromagnetic radiation coming from a computer, using a device that costs around $200 and can fit into a jacket pocket. Computers doing encryption must be physically secure to prevent this.</p><p>Even without physical access, if the same key is used too often there are known ways that attackers can determine the value of the key by analyzing large amounts of data encrypted using that key. In order to avoid this, the key must be changed <a href="https://www.cryptomathic.com/news-events/blog/symmetric-cryptography-and-key-management-considerations-on-key-exhaustion-rotation-and-security-models">regularly</a>, which is referred to as <strong>key rotation.</strong> However, when the key is changed, existing encrypted data must be decrypted using the old key and then re-encrypted using the new key. These computations can severely reduce performance for encrypted data.</p><h3>One Key to Rule Them All</h3><p>Instead of using the AES encryption key directly to encrypt data, Badger uses two types of keys:</p><ul><li>A user-provided AES encryption key, called the <strong>master key</strong>, is used to encrypt data keys.</li><li><strong>Data keys</strong> are generated automatically by Badger, and used to encrypt and decrypt data on disk. Each encrypted data key is stored on disk along with the encrypted data.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/804/1*LQdNfSPaUO3szAworluytQ.png" /><figcaption>Master key and Data keys</figcaption></figure><p>By default, Badger rotates the data keys every ten days, but this can be changed by the user.</p><p>The length of the master key provided by the user must be 16, 24 or 32 bytes. This determines what version of AES encryption is used (AES-128, AES-192, or AES-256 respectively).</p><p>Note that <strong>you should never use a predictable string as your master key.</strong> If you have a password manager (such as 1Password, LastPass, etc.), you can use its built-in password generator to generate a strong encryption key. Even if you don’t have a password manager, you can use a reputable online password generator, such as <a href="https://1password.com/password-generator/">1Password</a> to generate your master key.</p><p><strong>You should rotate your master key on a regular schedule.</strong> Fortunately, because the master key is used to encrypt only data keys, which are (even all together) much smaller compared to the data stored in the database, the master key does not need to be rotated as often (as data keys) to prevent key leak. Even better, when the master key is rotated, only the data keys need to be decrypted using the old master key, and then re-encrypted using the new master key. This is much faster than re-encrypting all of the data on disk.</p><h3>Avoiding Encrypted Duplicates</h3><p>When data keys are used to encrypt data stored in the database, the same data will often be encrypted multiple times before the rotation period for the data key expires. Encrypting the same data with the same data key always generates the same encrypted text to be stored in the database. This increases the ability of an attacker to reverse engineer the original plaintext data.</p><p>To reduce the predictability of the original data, Badger incorporates a standard encryption technique that doesn’t use the data key directly to encrypt the data. Instead, <strong>Badger generates a random 16-byte array called an </strong><a href="https://en.wikipedia.org/wiki/Initialization_vector"><strong>Initialization Vector</strong></a> (IV). The data key is used to encrypt the IV and then the encrypted IV is XORed with the user data, and the result is stored on disk. This means that even if the same block is encrypted multiple times, the random value of the IV ensures that the stored text will be different each time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/827/1*ysxOBbZrh0I5IZeVhpNezQ.png" /><figcaption>Initialization Vectors</figcaption></figure><p>In addition to reducing data predictability, the use of IVs increases performance because an XOR operation is vastly faster than running the AES encryption algorithm directly on the data to be encrypted. The overhead of this increased security and performance is the extra storage used for each 16-byte IV. Because of this, a potential issue with using IVs is that it can lead to data bloat.</p><h4>Reducing the Storage Overhead of IVs</h4><p>The files containing the keys are each divided into blocks, where each block is 4KB in size. Badger uses a unique IV to encrypt each of these blocks and stores the IV in plaintext at the end of the encrypted block. The storage overhead of a 16B IV over a 4KB block is 0.4%, which is reasonable.</p><p>Note that storing the IVs in plaintext is still secure. Assume that a cracker gets access to the IV and an encrypted block. To decrypt the block, they’d need to encrypt the IV with the data key (to XOR the encrypted data back to plaintext). But to get access to the data key, they’d need to decrypt it using the master key. If master key is safe and secure, that won’t be possible, rendering the effort futile. Thus, <strong>knowing the IV is not sufficient to decrypt the data.</strong></p><h4>Avoiding the bloat of attaching a 16-byte IV to every value</h4><p>Next, we need to encrypt the values stored in the vlog files. Each value is read individually from a vlog file, using the value pointer associated with each key, which stores the vlog file id, the offset in the file, and the size of the value. If we encrypt a whole block at a time, having multiple values in a block would cause a significant performance slowdown because considerable extra data would need to be decrypted to read an individual value.</p><p>As values are often accessed individually, we decided to <strong>encrypt each value individually</strong>. Because each encrypted value is required to have its own random IV, using one IV per value adds a 16B overhead for each value. For a vlog file that contains 10,000 entries, storing an IV with each value would require 160,000 bytes, which is not good.</p><p>It isn’t quite as bad as that, because small values are stored directly in the key files, instead of pointers, and that value gets decrypted along with its key. But even with this optimization, unless all values are very small it is easy to imagine that having one IV per value could double the size of a vlog file. Luckily, we came up with a better solution.</p><p>To optimize the encryption of the vlog entries, <strong>Badger uses a unique technique</strong>. Instead of generating a 16-byte IV and storing it at the end of each value in the vlog, Badger generates a single 12-byte IV that is used for all values in a vlog file. Along with it, Badger attaches 4 bytes that contain the offset of the value in the vlog file, which together make up the required 16-byte IV. For decryption, the 4-byte vlog offsets are available from the (decrypted) value pointer stored with each key. The 12-byte IVs are unique for each vlog, and the 4-byte offsets are unique within a single vlog file, so each composite 16-byte IV is also unique.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/806/1*7ng1ThfoyR2PGIQp7Ktguw.png" /><figcaption>Initialization Vectors for values in vlog files</figcaption></figure><p>This technique saves 16 bytes of space on disk for every value in a vlog file. Instead, this technique only requires 12 bytes per vlog file, regardless of the number of values in a file. That’s an even better savings than for the key files.</p><h3>Conclusion</h3><p>We added encryption to Badger using established and proven standards and best practices, implemented in a way that works well with the existing features and benefits of Badger. Most importantly, the addition of encryption did not appreciably slow Badger down, make it difficult or inconvenient to use, or significantly increase the storage used.</p><p>Badger is open source, and has been used as the storage engine for many large systems, and now it includes encryption for free. We hope Badger will make it easier for even more projects, especially ones that need to securely store encrypted data.</p><p><em>For more information about </em><a href="https://github.com/dgraph-io/badger/blob/master/README.md"><em>Badger</em></a><em>, see the </em><a href="https://blog.dgraph.io/tags/badger/"><em>Dgraph blog entries about it</em></a><em>, including this one about </em><a href="https://blog.dgraph.io/post/encryption-at-rest-dgraph-badger/"><em>encryption in Badger</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=63ca1e14edc4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Pitching Flutter to your company or client]]></title>
            <link>https://blog.flutter.dev/https-medium-com-flutter-io-pitching-flutter-2d4f494e47d1?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d4f494e47d1</guid>
            <category><![CDATA[future]]></category>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[tutorial]]></category>
            <category><![CDATA[dart]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Thu, 01 Nov 2018 18:06:36 GMT</pubDate>
            <atom:updated>2018-11-03T20:30:31.057Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<p>It has been over a year since <a href="https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514">What’s Revolutionary about Flutter</a> was published (it is still a good introduction). When I wrote that article, few mobile developers had heard about Flutter, but things have come a long way since then. Now I can’t keep up with all the articles and videos being created about Flutter by an active, vibrant, even <em>exploding</em> community. <a href="https://twitter.com/timsneath/status/1024684022574669824">Developers have discovered Flutter</a>, and <a href="https://medium.com/flutter-io/what-weve-learned-from-the-july-2018-flutter-user-survey-cbbf1e04370c">they <em>love it</em></a>. Here’s an animated GIF of just one of the <a href="https://itsallwidgets.com/">wonderful apps created using Flutter</a>, by <a href="https://medium.com/reflectly-engineering/reflectly-from-react-native-to-flutter-2e3dffced2ea">Reflectly</a>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*OOmIZ2plXASJUl49v6TlDA.gif" /><figcaption>Reflectly intelligent journaling Flutter app</figcaption></figure><p>Developers often tell me that one of their biggest challenges now is convincing their company management — or if they are an agency or freelancer, convincing their clients — to try Flutter. These decision-makers are not as eager to adopt the latest technology, just for technology’s sake. They are typically tech savvy, but that is not their only concern. They want to know if using something new will help their company succeed; for example, by bringing in new customers or reducing risks.</p><p>This article is aimed at two groups:</p><ul><li>Developers who want to help their management understand why they should use Flutter. Even if a developer is familiar with Flutter, they still need solid arguments to present to management.</li><li>Developers who want to decide for themselves whether to develop a product with Flutter.</li></ul><p>This article will also discuss reasons why a specific mobile app might not be a good target for Flutter, so an informed decision can be made.</p><h3>What is Flutter?</h3><p>The tagline for Flutter (kind of a written elevator pitch) is</p><blockquote><strong>Build beautiful native apps in record time</strong></blockquote><p>Let’s break this tagline up into four parts and discuss them one by one:</p><ol><li>Build</li><li>Beautiful</li><li>Native apps</li><li>In record time</li></ol><h3>1. Build</h3><p>Flutter is currently focused on building mobile apps for iOS and Android.</p><p>However, there is a larger, longer-term vision that sets Flutter apart from current mobile frameworks: Flutter is not just a <em>framework</em>, it is a <em>complete SDK</em> for building apps that interact using a screen. That means that Flutter contains everything needed to create a user interface, including the renderer and the things to be rendered (which Flutter calls <strong>widgets</strong>).</p><p>In many ways, Flutter is similar to game engines such as <a href="https://unity3d.com/">Unity</a> or <a href="https://www.unrealengine.com/">Unreal</a>, which also supply their own renderer and the things to be rendered (and other software). But instead of building <em>games</em>, Flutter builds <em>apps</em>.</p><p>The fact that Flutter is a complete SDK means that it can be ported to run on virtually any hardware that includes a display. The Flutter renderer uses <a href="https://en.wikipedia.org/wiki/Skia_Graphics_Engine">Skia, a popular open-source graphics engine</a> that is easy to use on different devices.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*_3mc2w0ZoMF86d5kbuvWwA.png" /><figcaption>Flutter on desktop and Raspberry Pi</figcaption></figure><p>While at Google we have been focused on mobile apps, various third parties have done ports of Flutter to <a href="https://github.com/google/flutter-desktop-embedding">desktop computers</a> (macOS shown at left, Windows, Linux, and <a href="https://groups.google.com/forum/?pli=1#!forum/flutter-desktop-embedding-dev">others</a>), to <a href="https://groups.google.com/forum/#!topic/flutter-dev/0Yf-b8fwGZs">TVs</a> (here’s a <a href="https://youtu.be/crODae5bIew">video of Flutter running on an Nvidia Shield TV</a>), and to the Raspberry Pi (shown at bottom left). Internally, Flutter is also used to build user interfaces for <a href="https://github.com/fuchsia-mirror">Fuchsia</a>.</p><p>Increasingly, apps will expand beyond mobile phones. It will be common to access apps across multiple devices, including home assistants (Google Home Hub, Lenovo Smart Display, etc.), interactive displays in cars, home appliances (refrigerators), wearables (watches, clothing), and other <a href="https://en.wikipedia.org/wiki/Internet_of_things">IoT</a> devices. In 2017 there were 8.4 billion such devices online. By 2020 (less than two years from now) <a href="https://www.businesswire.com/news/home/20131003005687/en/Internet-Poised-Change-IDC">IDC estimates</a> that there will be over 30 billion (compared to 5 billion mobile phones). Many of these devices will have interactive screens. Flutter’s architecture has all the ingredients to create <a href="https://www.forbes.com/sites/forbesnycouncil/2018/07/26/why-you-should-start-looking-at-googles-flutter-and-fuchsia-now/#228e36cca309">powerful and beautiful user interfaces for these new devices</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/949/1*0cJ-ZDludFJ-rcVp92lI8A.png" /><figcaption>Screens everywhere!</figcaption></figure><p>And of course, Flutter is completely free and open source.</p><h3>2. Beautiful</h3><p>How can you ensure the mobile app you are creating will succeed when it is competing against <a href="https://www.statista.com/statistics/276623/number-of-apps-available-in-leading-app-stores/">3.8 million apps in the Google Play Store and 2 million apps in the Apple App Store</a>? Even if you manage to convince a user to download your app, there is only a 3% chance that they will be actively using it 30 days later. Gartner Inc. says that <a href="https://www.forbes.com/sites/connieguglielmo/2014/01/13/mobile-apps-may-not-pave-the-way-to-developer-riches-sales-average-less-than-1250-a-day/#78025d324890">only 0.01% of all published mobile apps become a financial success</a>. Developers need all the help they can get.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/1*vFj6DgGFh43jJS6sX2ZxWw.jpeg" /><figcaption>Alibaba (left) and Topline (right)</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/277/1*HyTUK7HxEJfJZofdMGcSJA.gif" /><figcaption>2Dimensions</figcaption></figure><p>Studies have shown that having an <a href="https://medium.com/coffee-and-junk/design-psychology-aesthetic-usability-effect-494ed0f22571">appealing design can be very important</a>. If you look at the most popular mobile apps from the last few years, they each have their own design aesthetic. In addition, beautiful apps win awards, which provides valuable publicity.</p><p>As just a few examples, the Flutter apps shown to the left include apps <a href="https://hackernoon.com/making-the-most-of-flutter-from-basics-to-customization-433171581d01">from Alibaba</a> (the largest e-commerce company in the world), the <a href="https://www.abbeyroad.com/apps">Topline recording app</a> from Abbey Road Studios, and a demo app of amazing <a href="https://apkpure.com/2dimensions-showcase-unreleased/com.two_dimensions.showcaseapp">realtime animations from 2Dimensions</a>.</p><p>Increasingly, companies want their mobile apps to complement their company branding, just like they do for their website and web apps. This requires a <em>high degree of customization</em>.</p><p>Finally, designers often have great ideas that — by the time they are implemented — are badly watered down because of toolkit limitations. Flutter helps you <em>say yes to your designer</em> to build apps that implement their vision.</p><p>You can see more Flutter apps in the <a href="https://flutter.io/showcase/">Flutter showcase</a> (and hundreds more on the <a href="https://itsallwidgets.com/">It’s All Widgets site</a>). This includes the beautiful <a href="https://reflectly.app/">Reflectly journaling app</a>, shown at the beginning of this article using an animated GIF, but you should install it from the app stores onto your <a href="https://play.google.com/store/apps/details?id=com.reflectlyApp">Android</a> or <a href="https://itunes.apple.com/us/app/reflectly-mindfulness-journal/id1241229134">Apple</a> phone. Be sure to read about <a href="https://medium.com/reflectly-engineering/reflectly-from-react-native-to-flutter-2e3dffced2ea">their experiences switching their app to Flutter</a>.</p><h3>3. Native apps</h3><p>Mobile developers might be surprised by this point. In the world of mobile apps, the term “native app” is often used to refer to an app that targets platform APIs directly using specific languages. And just to make things more confusing, frameworks like React Native and Xamarin use the term “native” to mean that they can use the platform widgets.</p><p>Other areas of computing don’t really use the term “native” as it is used in mobile. For example, you can install Linux on either Windows and macOS computers (and many other kinds), but you wouldn’t call Windows or macOS “native” and Linux a “cross-platform” or “hybrid” solution. People consider Linux just as native as Windows or macOS, <em>because it is</em>.</p><p>A more precise <a href="https://en.oxforddictionaries.com/definition/native">definition of “native” for computing</a> is:</p><blockquote>“Designed for or built into a given system, <strong>especially denoting the language associated with a given processor</strong>, computer, or compiler, and programs written in it.”</blockquote><p>Flutter apps are compiled to native machine (<a href="https://en.wikipedia.org/wiki/ARM_architecture">ARM</a>) code on both iOS and Android.</p><p>The advantages of native apps are plentiful. Native apps start up faster, and most importantly they are smoother and less likely to suffer from jerkiness or stutter (<em>jank is not beautiful</em>). Native apps also give the developer more control over the behavior of their app.</p><p>In order to receive the advantages of native apps, mobile developers have typically built two separate apps using separate tools and languages. Often, this means having distinct teams of developers for each platform, who then have to coordinate with each other. This raises costs significantly, increases risks, and slows the time to market. Flutter allows developers to consolidate into a single codebase, unify their development teams, reduce risk, and speed time-to-market. All while getting the benefits of a native app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*EJba6N3Cb1qa1DUdcc0-kQ.gif" /><figcaption>Which one is “native”? Both!</figcaption></figure><p>What about the widgets? Because <a href="https://medium.com/flutter-io/why-flutter-doesnt-use-oem-widgets-94746e812510">Flutter provides its own widgets</a>, you might be afraid that Flutter apps will look or feel uncannily different than apps developed using the platform widgets and tools.</p><p>To the left, the iOS platform settings screen is compared to the same screen created using Flutter. Even though there are a few small differences at the pixel level, the bottom line is that Flutter makes it easy to create screens that look and feel like platform screens.</p><p>Because platforms change between different OS versions, even a platform native app will typically look different on distinct versions of an OS. It is virtually meaningless for Flutter to try to be “pixel perfect”.</p><p>Flutter’s widgets adapt to the platform they are running on to provide the proper look and feel, including icons, colors, layout, fonts, scrolling behavior, and so forth. Instead of being “pixel perfect” a more important goal for a Flutter app is to conform to the design guidelines for the platform, and to feel familiar and comfortable to the user.</p><p>The high platform fidelity of Flutter apps is possible because Flutter is a complete SDK that renders directly to the platform canvas. Your app does not depend on the platform’s widgets, fonts, etc. that might change out from underneath it.</p><p>Flutter also avoids the need for <a href="https://developer.android.com/topic/libraries/support-library/">compatibility libraries</a>. For example, here is a Flutter app that uses Material Design widgets, on a phone running Android Jelly Bean (4.1.2). This phone came out <em>two years before</em> Material Design was even created, so the phone has no built-in widgets for Material Design at all. But your Flutter app will run the same as it does on a more modern phone with a more recent OS, and look great.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/690/1*-ehN32qJg_iFuBjuMdUYew.png" /></figure><p>Without Flutter, you would have to deal with these problems yourself. This means more testing on older versions of the OS, and workarounds for platforms that don’t provide features that your app uses. Developers tell us that testing is dramatically easier using Flutter.</p><p>In summary, Flutter not only provides the advantages of native apps, it provides additional important benefits:</p><ul><li>Flutter apps will run on older versions of each platform OS. For example, if you, the developer, test your Flutter app on a recent version of Android, it will look the same on older versions. This allows Flutter apps to run well on older phones, with far less testing.</li><li>New releases of the platform OS will also never break your app, unless a change breaks something on which Flutter depends (this is extremely rare, and would be a bug in Flutter, not in your app).</li><li>Your app will not look dramatically different because of modifications made to the OS made by manufacturers or carriers (a common example is changes to the default fonts).</li><li>Most importantly, Flutter gives you, the developer, complete control over what your app looks like, <em>down to the pixel</em>, on all platforms and versions.</li><li>If desired, you can explicitly make a Flutter app look different on iOS and Android. Even if you don’t do this, the Flutter widgets adapt to the design guidelines for each platform.</li><li>Flutter can do this using a single codebase for both platforms. Or you can <a href="https://flutter.io/platform-channels/">add platform native code for each platform</a> to a Flutter app, if desired.</li></ul><h3>4. In record time</h3><p>Last, but certainly not least, Flutter lets you develop <em>better</em> apps <em>faster</em>. The most popular (and even hyped) feature of Flutter is its <em>stateful hot reload</em>. Not only is it amazingly fast (usually sub-second), it is stateful, which means if you change some code deep down in your app, after you recompile you don’t have to navigate back into the same place or manually recreate your state in order to see the effect of the change.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DDzx3KU38jeAs2gWYc1KVQ.gif" /><figcaption>Stateful hot reload!</figcaption></figure><p>Flutter’s stateful hot reload is made possible by advanced compiler technology (developed by some of the same people who built the <a href="https://en.wikipedia.org/wiki/Chrome_V8">V8 compiler</a> for JavaScript and <a href="https://en.wikipedia.org/wiki/Strongtalk">Strongtalk</a> for Smalltalk) and the fact that Flutter is native and based on reactive views.</p><p>In addition to speeding things up, many developers report that Flutter dramatically changes the way they code. They can try out new ideas and new layouts quickly. They can make changes requested by their stakeholders right in front of them.</p><p>We also find that it helps designers get exactly what they want. They can play with various parameters until it looks just right. Indeed, designers who know how to use CSS in web apps tell us that it is <a href="https://youtu.be/BJCqRpvvTrM">easy for them to learn</a> how to make changes themselves to layouts in Flutter .</p><p>To really appreciate this, <a href="https://youtu.be/iflV0D0d1zQ">watch a Flutter app live coded</a> in real time, or try Flutter yourself to build a real app. Join a Flutter hackathon and see how quickly you can learn Flutter and build a working app in it.</p><p>As discussed in the last section, Flutter apps also require less testing, which means that you can test and deliver new features for your app much more quickly. For example, JD.com tells us:</p><blockquote>We were able to develop the same features with half of the development resource. With the same number of engineers, each release can now have more features.</blockquote><p>Likewise, <a href="https://hackernoon.com/making-the-most-of-flutter-from-basics-to-customization-433171581d01">Alibaba</a> tells us that using Flutter, the average time to add a new feature went from a month down to two weeks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CPLZMvIh93Amt_RvTJ8lPg.png" /><figcaption>Hamilton, the app</figcaption></figure><p>In <a href="https://youtu.be/kfd-oLypqFI">the Hamilton app</a>, the developers actually made a major change to the app <em>the night before</em> they released it, with the confidence that the app would be rock solid. That app, built in three short months, was featured on both app stores. Plus Flutter makes it easier for them continue to add new features frequently, to keep their users active and coming back for more.</p><p>That’s how you build a successful mobile app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/934/1*PyYYwZB4TXMqF7W3SHVv0w.jpeg" /></figure><p>Not only is it easy and fast to build and modify your apps, it is just as fast to update the Flutter widgets. A common concern about Flutter not using the platform widgets is that Flutter will struggle to keep up with the platforms as they release new widgets or improve old ones.</p><p>However, when Apple announced their new iPhone X with its notch, Flutter was able to add support for the notch before the phone itself was released.</p><p>And this doesn’t only apply to iOS features. When Google announced a <a href="https://material.io/design/material-theming/">significant revamp of Material Design</a> at I/O 2018, Flutter was already updated to fully implement the new features. The ability of Flutter to be quickly customized made this possible.</p><p>The bottom line is that developers frequently report that they are between two and three times more productive using Flutter, and that they build better apps that are more successful.</p><h3>Risks and limitations</h3><p>There are always a few tradeoffs, and Flutter is no exception. Here are some reasons why Flutter may not be the best tool for a specific app, so that you can make an informed decision.</p><p>Because Flutter apps include the Flutter widgets and renderer, this makes the resulting apps slightly larger than apps that utilize the platform widgets and renderer. Up until recently, a Flutter app had a minimum size of 6.7MB, but that has been <a href="https://twitter.com/flutter_wm/status/1025747957608411137">reduced to a little over 4MB</a>. We plan to make further optimizations in the future.</p><p>One of the major benefits of Flutter is that a single codebase can be used to release apps on both mobile platforms (although Flutter is also used to build apps for only a single platform). However, there are some apps that are tightly tied to one specific platform or are primarily a wrapper around a platform-provided view, such as an app that is mainly a background service to provide notifications. These apps can be written in Flutter, but they will not see as much benefit from it.</p><p>A question we are often asked is whether Flutter is here to stay. There are multiple reasons why the answer is an <em>emphatic yes</em>. First, Google is itself a heavy user of Flutter, including for both customer-facing and internal apps (with more apps being developed). For example, the recently released Google Ads mobile app (formerly called AdWords) is written in Flutter. Google is solidly behind Flutter and is committed to its success.</p><p>Second, the fact that major apps have typically been built on two separate platforms means that companies have often considered it less risky to (for example) first build an iOS app, and then build an Android app later if there is enough demand. With Flutter, <a href="https://medium.com/flutter-community/porting-a-75-000-line-native-ios-app-to-flutter-57c6571c57b4">apps can be released simultaneously on both platforms</a> with virtually identical features, circumventing that risk and increasing the potential market for an app. This can be a big benefit to Android.</p><p>Another potential issue is that Flutter is comparatively new. It will naturally take a little time for Flutter to catch up to the incumbent tools, both in terms of features and community support. Presently, there are some features provided by the platforms that will take some time for Flutter to implement. Google is putting the resources into Flutter to add these features.</p><p>If you want deeper information on why it is worthwhile to try Flutter, read <a href="https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514">What’s Revolutionary about Flutter</a> and <a href="https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf">Why Flutter uses Dart</a>. And read the results of <a href="https://medium.com/flutter-io/what-weve-learned-from-the-july-2018-flutter-user-survey-cbbf1e04370c">our latest user study</a> to see what users of Flutter think about it.</p><h3>How to get started</h3><p>When you are ready to try Flutter, here some helpful things:</p><ol><li><a href="https://flutter.io/get-started/">https://flutter.io/get-started/</a> — this guide helps you install Flutter, configure your editor, go for a test drive, and write your first app.</li><li>Watch some <a href="https://www.youtube.com/results?search_query=Flutter">Flutter videos on YouTube</a>.</li><li>There are a set of guides for devs who are familiar with one (or more) of the following: <a href="https://flutter.io/flutter-for-android/">Android</a>, <a href="https://flutter.io/flutter-for-ios/">iOS</a>, <a href="https://flutter.io/flutter-for-react-native/">React Native</a>, <a href="https://flutter.io/flutter-for-xamarin-forms/">Xamarin</a>.</li><li>Or if you are new to mobile development, there are also tutorials, such as: <a href="https://flutter.io/tutorials/layout/">Building Layouts in Flutter</a>, <a href="https://flutter.io/tutorials/interactive/">Add Interactivity</a>, and <a href="https://flutter.io/widgets-intro/">A Tour of the Flutter Widget Framework</a> (including reactive principles, if you are not familiar with them).</li><li>A valuable resource is the <a href="https://flutter.io/cookbook/">Flutter cookbook</a>. Also the <a href="https://flutter.io/widgets/">Widget catalog</a> and <a href="https://flutter.io/faq/">the FAQ</a>.</li><li>Similarly, look at the apps in <a href="https://itsallwidgets.com/">It’s All Widgets</a>. Many of these are open source, so you can see code for published apps. And once you write your own Flutter apps, be sure to submit them.</li><li>To get a list of the best articles about Flutter delivered to your inbox each week, <a href="https://flutterweekly.net/">subscribe to Flutter Weekly</a>.</li><li>There are a bunch of lovely <a href="https://codelabs.developers.google.com/?cat=Flutter">codelabs for Flutter</a>, and if that isn’t enough there is a <a href="https://www.udacity.com/course/build-native-mobile-apps-with-flutter--ud905">free online video course on Flutter</a> from Udacity.</li><li>And <a href="https://flutter.io/get-started/learn-more/">plenty of other documentation here</a>.</li></ol><p>To get involved in the Flutter community, you can find us on <a href="https://twitter.com/flutterio">Twitter</a>, <a href="https://gitter.im/flutter/flutter">Gitter</a>, and <a href="https://stackoverflow.com/tags/flutter">Stack Overflow</a>. You should subscribe to the <a href="https://groups.google.com/forum/#!forum/flutter-dev">Flutter Dev mailing list</a>. And find a local Flutter Meetup or Study Jam, and see if there are any mobile app hackathons happening near you.</p><h3>Conclusions</h3><p>Flutter provides high-velocity development that makes you more productive and helps you build better apps. It is an expressive, highly flexible, and customizable toolkit that gives you, the developer, awesome amounts of control. And it creates fast and smooth native iOS and Android apps from a single codebase.</p><p>Flutter will save you money and reduce risks. It is free and open source. Flutter will also help you make more money. You can go after both the Android and iOS markets simultaneously, and create better apps in less time.</p><p>Developers also say (<em>and this is one of my favorite things</em>) that <a href="https://medium.com/@matthew.smith_66715/why-we-chose-flutter-and-how-its-changed-our-company-for-the-better-271ddd25da60">Flutter makes mobile development fun again</a>. An outstanding <a href="https://medium.com/flutter-io/what-weve-learned-from-the-july-2018-flutter-user-survey-cbbf1e04370c">92% of developers</a> who use Flutter say they are <em>satisfied</em> or <em>very satisfied</em> with it. This number has been steadily increasing, and remember that these results are all from the alpha and beta versions of Flutter, <em>before</em> the 1.0 release.</p><p>Finally, Flutter looks to the future. It is the only native mobile toolkit that supports reactive views, a programming paradigm that helps build better apps, and also enables things like super-fast stateful hot reload. And because it is a complete SDK, Flutter can remain relevant by being ported to new platforms as they become popular.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d4f494e47d1" width="1" height="1" alt=""><hr><p><a href="https://blog.flutter.dev/https-medium-com-flutter-io-pitching-flutter-2d4f494e47d1">Pitching Flutter to your company or client</a> was originally published in <a href="https://blog.flutter.dev/">Flutter</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Perspective on Flutter]]></title>
            <link>https://blog.flutter.dev/perspective-on-flutter-6f832f4d912e?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/6f832f4d912e</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[spotlight]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[3d]]></category>
            <category><![CDATA[flutter]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Mon, 18 Jun 2018 04:46:08 GMT</pubDate>
            <atom:updated>2019-02-07T21:12:29.755Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<h4>Fun with 3D and the Transform widget</h4><p>tl;dr — The Transform widget allows you to do amazing things in your Flutter apps. Here’s a one-minute video showing off what developers have done with Transform widgets:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F9z_YNlRlWfA%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D9z_YNlRlWfA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F9z_YNlRlWfA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd9b79b898f47f90dc85f60a89484155/href">https://medium.com/media/cd9b79b898f47f90dc85f60a89484155/href</a></iframe><p>This article builds a simple demo program that shows how to use Flutter’s <a href="https://docs.flutter.io/flutter/widgets/Transform-class.html">Transform</a> widget to provide 3D perspective, a <em>graphic</em> demonstration of the ease with which Flutter can do something that would be rather difficult to implement in a system based on native widgets. It is also fun to play with!</p><p>Here’s the app we are going to build in action (the little circle reflects the position of the user’s finger on the screen):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/540/1*WdpLQEC_L1PYDO1KgxxfMQ.gif" /></figure><h3>Getting started</h3><p>This example starts with the familiar default Flutter app — what you get when you do a flutter create or use your IDE to generate a new Flutter project. We are going to add two new things to this app: a <a href="https://docs.flutter.io/flutter/widgets/Transform-class.html">Transform</a> widget and a <a href="https://docs.flutter.io/flutter/widgets/GestureDetector-class.html">GestureDetector</a> widget.</p><p>First the transform:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f25996dea8d6e82a5d404e1488cda5c3/href">https://medium.com/media/f25996dea8d6e82a5d404e1488cda5c3/href</a></iframe><p>Running this code shows the default app being transformed slightly in 3D, with perspective:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/427/1*_hmzjJSeyWTnPccV5BsOHg.png" /></figure><p>We also removed some things we didn’t need, including all the extra comments, and (in honor of <a href="https://www.dartlang.org/dart-2">Dart 2</a>) all the new keywords. For demonstration purposes we moved the layout part of the default app (the build method of _MyHomePageState) to a separate method called _defaultApp (lines 49–74). And for simplicity we set the AppBar title on line 52, rather than passing it as a parameter to MyHomePage.</p><h3>Transform widget</h3><p>The added <a href="https://docs.flutter.io/flutter/widgets/Transform-class.html">Transform</a> widget is on lines 39–46. Let’s look at this more closely. Transform takes a 3D <a href="https://en.wikipedia.org/wiki/Transformation_matrix">transformation matrix</a>, which is a <a href="https://docs.flutter.io/flutter/vector_math/Matrix4-class.html">Matrix4</a>. Why a 3D matrix? Isn’t Flutter for two-dimensional graphics? Well, kind of.</p><p>Pretty much all but the least powerful smartphones include amazingly fast <a href="https://en.wikipedia.org/wiki/Graphics_processing_unit">GPUs</a>, which are optimized for 3D graphics. That means that rendering 3D graphics is <em>very fast</em>. Consequently, almost everything you see on your phone is being rendered in 3D, even the 2D stuff. Crazy, huh?</p><p>Setting the transformation matrix lets us manipulate what is being viewed (in 3D even!). Common transformations include translate, rotate, scale, and perspective. To create this matrix we start with an <a href="https://docs.flutter.io/flutter/vector_math/Matrix4/Matrix4.identity.html">identity matrix</a> (line 40) and then apply transformations to it. Transformations are not <a href="https://en.wikipedia.org/wiki/Commutative_property">commutative</a>, so we have to apply them in the right order. The final complete matrix will be sent to the GPU to transform the objects being rendered.</p><p>Transformations are a complicated subject, but if you want to learn more about them you can read any introduction to 3D graphics on <a href="https://en.wikipedia.org/wiki/Transformation_matrix">transformation matrices</a> and <a href="https://en.wikipedia.org/wiki/Homogeneous_coordinates">homogeneous coordinates</a>.</p><h3>Perspective</h3><p>The first transformation (on line 41) implements perspective. <a href="https://en.wikipedia.org/wiki/Perspective_(graphical)">Perspective</a> makes objects that are farther away appear smaller. Setting row 3, column 2 of the matrix to 0.001 scales things down based on their distance.</p><p>Where did the number 0.001 come from? Thin air! You can play with this number to increase and decrease the amount of perspective, something like zooming in and out with a zoom lens on a camera. The bigger this number, the more pronounced is the perspective, which makes it look like you are closer to the viewed object.</p><p>Flutter does provide a <a href="https://docs.flutter.io/flutter/vector_math/makePerspectiveMatrix.html">makePerspectiveMatrix</a> function but that method includes arguments for setting the aspect ratio, field of view, and near and far planes — way more than we need — so we will just set the required element of the matrix directly.</p><h3>Rotations</h3><p>Next on lines 42 and 43 we apply two rotations based on the value of the _offset variable (from line 29; later we will use this variable to track the position of the user’s finger). Curiously, the X rotation is based on the Y offset, and the Y rotation is based on the X offset. Why?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/424/1*sSCRNrjBJYifAMUMpIbL7A.png" /></figure><p>Consider this image, which has added green arrows showing the X and Y axes for the display. The default origin of these axes is the upper left corner of the display (which is why the Y axis points down), but our program sets the origin (in line 44) to be the center of the display .</p><p>Rotation is defined about an axis, so rotateX defines rotation around the X axis, which tilts in the Y (up-down) direction. Likewise, rotateY tilts in the X (left-right) direction (around the Y axis). That’s why rotateX is controlled by _offset.dy and rotateY is controlled by _offset.dx.</p><p>There is also a Z axis, whose origin is at the surface of the screen running perpendicular to the screen through the phone and out the back, so that the Z value goes positive the further away a thing is from the viewer. Consequently, the rotateZ method rotates in the plane of the display.</p><h3>Interaction</h3><p>The second and final thing we are going to add is a <a href="https://docs.flutter.io/flutter/widgets/GestureDetector-class.html">GestureDetector</a> widget. This is very easy in Flutter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2bcbad961f9e22cc7e69839064aa90a8/href">https://medium.com/media/2bcbad961f9e22cc7e69839064aa90a8/href</a></iframe><p>In line 28, _offset is initialized to zero. Lines 44–48 define a GestureDetector that detects two kinds of gestures: pan gestures (e.g., a finger moving around the screen) and double tap gestures. Line 45 adds the amount of pan movement (in pixels) to _offset. Line 46 resets the _offset to zero when the user double taps the display. For both of these gestures, setState() schedules the display to be redrawn.</p><p>Finally, lines 41 and 42 are modified so that the offset (in pixels) is scaled by a factor of 0.01 to make it better to use for rotation (which is in radians, where a complete rotation is 2π — approximately 6.28 — so a complete rotation requires a pan movement of 628 pixels). You can play with the scale factor to make the rotation more or less sensitive to finger movement. Also, the parameter to rotateY is negated because as the finger moves to the right, the image rotates counter-clockwise around the Y axis (because the Y axis is pointing downward).</p><h3>Done!</h3><p><a href="https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514">In Flutter</a>, almost everything is in the app itself (rather than in the platform), including the widgets and renderer. This gives great flexibility. In this case, we had easy access to powerful features provided by the GPU, and even a widget to help us. Our changes consist of a mere 13 lines of code. Not bad!</p><p>Note that after you rotate the default app around the X or Y axis, you might have difficulty tapping the FAB to increment the counter. Flutter does compensate for most transforms, including scale and rotateZ, so the UI will still work properly in those cases, but it has some problems with full 3D transforms. We’re working on fixing that.</p><p>Of course, none of the objects in the default app are actually 3D. They are all 2D (flat) objects (even the faux shadows cast by the AppBar and FAB). But that doesn’t stop us from spinning them around in 3D space.</p><h3>Further ideas</h3><p>There is so much you could do with this simple program, often with just a few lines of code:</p><ul><li>Make the same changes to some app that is more complex than the default app.</li><li>Add a spin around the Z axis, using rotateZ.</li><li>Change the amount of perspective so that it is a negative number. What do you think will happen?</li><li>Translate the <a href="https://docs.flutter.io/flutter/material/FloatingActionButton-class.html">FAB</a> a bit in the negative Z direction so that it is floating slightly above the body of the <a href="https://docs.flutter.io/flutter/material/Scaffold-class.html">Scaffold</a> widget. For extra points, create a “real” shadow instead of a faux one.</li><li>Add an animation so that when the user’s finger releases from the screen the app keeps spinning, slowing down to a stop. You can do this with the onPanEnd argument to the GestureDetector, which provides the <a href="https://docs.flutter.io/flutter/gestures/DragEndDetails-class.html">velocity of the finger</a> (in pixels per second) as it loses contact with the screen.</li><li>Create a 3D transition between two screens or tabs in an app. For example, like turning the pages of a book, or one screen spinning and becoming another.</li></ul><p>If you think of other ideas, let me know in the comments.</p><p>UPDATE: A shout out to the article “<a href="https://medium.com/flutter-community/make-3d-flip-animation-in-flutter-16c006bb3798">Make 3D flip animation in Flutter</a>”, which references this article to add perspective to a flip animation, like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/270/1*cWO2jnAleFiGh8J-vvpNrQ.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6f832f4d912e" width="1" height="1" alt=""><hr><p><a href="https://blog.flutter.dev/perspective-on-flutter-6f832f4d912e">Perspective on Flutter</a> was originally published in <a href="https://blog.flutter.dev/">Flutter</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Flutter Uses Dart]]></title>
            <link>https://medium.com/hackernoon/why-flutter-uses-dart-dd635a054ebf?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/dd635a054ebf</guid>
            <category><![CDATA[dart]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[dartlang]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Mon, 26 Feb 2018 12:26:01 GMT</pubDate>
            <atom:updated>2019-04-02T17:39:05.929Z</atom:updated>
            <content:encoded><![CDATA[<p>Many linguists believe that the natural language a person speaks <a href="https://en.wikipedia.org/wiki/Linguistic_relativity">affects how they think</a>. Does the same concept apply to <a href="https://en.wikipedia.org/wiki/Programming_language">computer languages</a>? Programmers working in different kinds of programming languages often come up with radically different solutions to problems. As a more extreme example, computer scientists <a href="https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf">eliminated the <em>goto</em> statement</a> to encourage more structured programs (not quite the same as totalitarian leaders in the <a href="https://en.wikipedia.org/wiki/Nineteen_Eighty-Four">novel <em>1984</em></a> expunging heretical words from natural language to eliminate <a href="https://en.wikipedia.org/wiki/Thoughtcrime"><em>thoughtcrimes</em></a>, but you get the idea).</p><p>What does this have to do with <a href="https://flutter.io/">Flutter</a> and <a href="https://www.dartlang.org/">Dart</a>? Quite a bit actually. The early Flutter team evaluated more than a dozen languages, and picked Dart because it matched the way they were building user interfaces.</p><p>Dart is a big reason why developers love Flutter. As <a href="https://twitter.com/Jordy_vD_/status/950277357734162432">one tweet puts it</a>:</p><h3>Jordy on Twitter</h3><p>@flutterio got me to look at @dart, and I&#39;m glad I took it for a spin. #Dart is an awesome language, and #flutterio takes it even further, to mobile devices &amp;lt;3</p><p>Here is a quick list of the Dart features that together make it indispensable for Flutter:</p><ul><li>Dart is AOT (Ahead Of Time) compiled to fast, predictable, native code, which allows almost all of Flutter to be written in Dart. This not only makes Flutter fast, virtually everything (including all the widgets) can be customized.</li><li>Dart can also be JIT (Just In Time) compiled for exceptionally fast development cycles and game-changing workflow (including Flutter’s popular sub-second stateful hot reload).</li><li>Dart makes it easier to create smooth animations and transitions that run at 60fps. Dart can do object allocation and garbage collection without locks. And like JavaScript, Dart avoids preemptive scheduling and shared memory (and thus locks). Because Flutter apps are compiled to native code, they do not require a slow bridge between realms (e.g., JavaScript to native). They also start up much faster.</li><li>Dart allows Flutter to avoid the need for a separate declarative layout language like JSX or XML, or separate visual interface builders, because Dart’s declarative, programmatic layout is easy to read and visualize. And with all the layout in one language and in one place, it is easy for Flutter to provide advanced tooling that makes layout a snap.</li><li>Developers have found that Dart is particularly easy to learn because it has features that are familiar to users of both static and dynamic languages.</li></ul><p>Not all of these features are unique to Dart, but the combination of them hits a <em>sweet spot</em> that makes Dart uniquely powerful for implementing Flutter. So much so, it is hard to imagine Flutter being as powerful as it is without Dart.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/663/1*bAUFoOPQ3gcv7y4Kdz82tw.png" /><figcaption>Flutter loves Dart</figcaption></figure><p>The rest of this article goes into more depth about many of the characteristics of Dart (including its standard libraries) that make it the <em>best language for implementing Flutter</em>.</p><h3>Compilation and execution</h3><p><em>[You can skip this section if you already know about topics like static versus dynamic languages, AOT and JIT compilation, and virtual machines.]</em></p><p>Historically, computer languages have been divided into two groups: <a href="https://en.wikipedia.org/wiki/Compiled_language"><em>static</em> languages</a> (e.g., Fortran or C, where variables are statically typed at compile time), and <a href="https://en.wikipedia.org/wiki/Interpreted_language"><em>dynamic</em> languages</a> (e.g., Smalltalk or JavaScript, where the type of a variable can change at run time). Static languages were typically compiled to produce native machine code (or <em>assembly code</em>) programs for the target machine, which at run time were executed directly by the hardware. Dynamic languages were executed by an interpreter, without producing machine language code.</p><p>Of course, things eventually became much more complicated. The concept of a <a href="https://en.wikipedia.org/wiki/Virtual_machine">virtual machine</a> (VM) became popular, which is really just an advanced interpreter that mimics a hardware machine in software. A virtual machine makes it easier to port a language to new hardware platforms. In this case, the input language of a VM is often an <a href="https://en.wikipedia.org/wiki/Intermediate_representation#Intermediate_language">intermediate language</a>. For example, a programming language (such as <a href="https://en.wikipedia.org/wiki/Java_(programming_language)">Java</a>) is compiled into a intermediate language (<a href="https://en.wikipedia.org/wiki/Java_bytecode"><em>bytecode</em></a>) and then executed on a VM (the <a href="https://en.wikipedia.org/wiki/Java_virtual_machine"><em>JVM</em></a>).</p><p>In addition, there are now <a href="https://en.wikipedia.org/wiki/Just-in-time_compilation"><em>just-in-time</em> (JIT) compilers</a>. A JIT compiler runs during execution of the program, compiling on the fly. The original compilers that execute during creation of the program (before runtime) are now called <a href="https://en.wikipedia.org/wiki/Ahead-of-time_compilation"><em>ahead-of-time</em> (AOT) compilers</a>.</p><p>In general, only static languages are amenable to AOT compilation into native machine code because machine languages typically need to know the type of data, and in dynamic languages the type is not fixed ahead of time. Consequently, dynamic languages are typically interpreted or JIT compiled.</p><p>When AOT compilation is done during development, it invariably results in much slower development cycles (the time between making a change to a program and being able to execute the program to see the result of the change). But AOT compilation results in programs that can execute more predictably and without pausing for analysis and compilation at runtime. AOT compiled programs also start executing faster (because they have already been compiled).</p><p>Conversely, JIT compilation provides much faster development cycles, but can result in slower or jerkier execution. In particular, JIT compilers have slower startup times, because when the program starts running the JIT compiler has to do analysis and compilation before the code can be executed. Studies have shown that <a href="https://www.google.com/search?q=slow+startup+times+lead+to+abandonment">many people will abandon an app if it takes more than a few seconds to start executing</a>.</p><p>That’s the end of the background info. Wouldn’t it be awesome to combine the advantages of both AOT and JIT compilation? Read on.</p><h4>Compiling and executing Dart</h4><p>Before working on Dart, the Dart team members had done groundbreaking work on advanced compilers and virtual machines, both for dynamic languages (like the <a href="https://en.wikipedia.org/wiki/Chrome_V8">V8 engine</a> for JavaScript and <a href="https://en.wikipedia.org/wiki/Strongtalk">Strongtalk</a> for Smalltalk) and for static languages (like the <a href="https://en.wikipedia.org/wiki/HotSpot">Hotspot compiler</a> for Java). They used this experience to make Dart unusually flexible in how it can be compiled and executed.</p><p>Dart is one of very few languages (and perhaps the only “mainstream” language) that is well suited to being compiled both AOT and JIT. Supporting both kinds of compilation provides significant advantages to Dart and (especially) Flutter.</p><p>JIT compilation is used during development, using a compiler that is especially fast. Then, when an app is ready for release, it is compiled AOT. Consequently, with the help of advanced tooling and compilers, Dart can deliver the best of both worlds: extremely fast development cycles, <em>and</em> fast execution and startup times.</p><p>Dart’s flexibility in compilation and execution doesn’t stop there. For example, Dart can be <a href="https://webdev.dartlang.org/tools/dart2js">compiled into JavaScript</a> so it can be executed by browsers. This allows code reuse between mobile apps and web apps. Developers have <a href="https://medium.com/@matthew.smith_66715/why-we-chose-flutter-and-how-its-changed-our-company-for-the-better-271ddd25da60">reported as high as 70% code reuse</a> between their mobile and web apps. Dart can also be used on a server either by being compiled to native code, or by compiling to JavaScript and using it with <a href="https://nodejs.org/en/">node.js</a>.</p><p>Finally, <a href="https://www.dartlang.org/dart-vm/tools/dart-vm">Dart also provides a standalone VM</a> that uses the Dart language itself as its intermediate language (essentially acting like an interpreter).</p><p>Dart can be efficiently compiled AOT or JIT, interpreted, or transpiled into other languages. Not only is Dart compilation and execution unusually flexible, it is especially <em>fast</em>.</p><p>The next section provides an example of how Dart’s compilation speed can be a game changer…</p><h4>Stateful hot reload</h4><p>One of the most popular features of Flutter is its extremely fast <em>hot reload</em>. During development, Flutter uses a JIT compiler that can reload and continue executing code usually in under a second. App state is retained across reloads whenever possible, so the app can continue from where it left off.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/864/1*c1dM9uhkRj9_fpiDrLJmDw.gif" /><figcaption>Flutter’s sub-second stateful hot reload</figcaption></figure><p>It is hard to appreciate how important really fast (and reliable) hot reload can be during development, unless you have experienced it yourself. Developers report that it changes the way they create their apps, describing it as being like <a href="https://github.com/zilongc/blog/issues/3">painting their app to life</a>.</p><p>Here’s what one <a href="https://medium.com/@lets4r/the-fluture-is-now-6040d7dcd9f3">mobile app developer says about Flutter’s hot reload</a>:</p><blockquote>I wanted to test the hot reloading, so I changed a color, saved my modification, and… fell in love ❤️!</blockquote><blockquote>This feature is really amazing. I thought the <strong>Edit &amp; Continue</strong> in Visual Studio was good, but this is simply <strong>astounding</strong>. Only with this, I think a mobile developer can be two times more productive.</blockquote><blockquote>This is really a game changer for me. When I deploy my code and it takes a long time, I lose my focus, I do something else and when I come back to the simulator/device I have lost track of what I wanted to test. What’s more frustrating than losing 5 minutes to move a control by 2px? With Flutter this no longer exists.</blockquote><p>Flutter’s hot reload makes it far easier to try new ideas or experiment with alternatives, providing a huge boost to creativity.</p><p>So far, we’ve discussed how Dart makes things better for the developer. The next section is about how Dart also makes it easier to create smooth apps that delight users.</p><h3>Avoiding jank</h3><p>A <em>fast</em> app is great, but a <em>smooth</em> app is even better. Even a super fast animation will look bad if it is jerky. However, preventing <a href="https://afasterweb.com/2015/08/29/what-the-jank/">jank</a> can be difficult because there are so many different causes. Dart has a number of features to avoid many of the common things that cause jank.</p><p>Of course, (like any language) it is still possible to write a janky app in Flutter; Dart helps by being more predictable and giving the developer more control over the smoothness of their app, making it easier to provide the best user experience possible, bar none.</p><p><a href="https://code.tutsplus.com/tutorials/developing-an-android-app-with-flutter--cms-28270">The results</a>?</p><blockquote>Running at 60 fps, user interfaces created with Flutter perform far better than those created with other cross-platform development frameworks.</blockquote><p>And not just better than cross-platform apps, but as good as the best native apps:</p><blockquote>The UI is butter smooth… I have never seen such a smooth Android app.</blockquote><h4>AOT compilation and the “bridge”</h4><p>We’ve already discussed one feature that helps keep things smooth, and that is Dart’s ability to be AOT compiled to native machine code. Pre-compiled AOT code is more predictable than JIT because there are no pauses during runtime to perform JIT analysis or compilation.</p><p>However, there is an even bigger advantage to AOT compiled code and that is avoiding the “JavaScript bridge”. When dynamic languages (like JavaScript) need to interoperate with native code on the platform, <a href="https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514">they have to communicate over a bridge</a>, which <a href="https://medium.com/@talkol/performance-limitations-of-react-native-and-how-to-overcome-them-947630d7f440">causes context switches</a> that have to save a particularly large amount of state (potentially to secondary storage). These <a href="https://en.wikipedia.org/wiki/Context_switch">context switches</a> are a double whammy because they not only slow things down, they can cause serious jank.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_fK1BtH5V-kO828lPg-Ukw.png" /><figcaption>“The Bridge”</figcaption></figure><p>Note: even compiled code may need an interface to talk to platform code, and this can also be called a bridge, but it is typically orders of magnitude faster than the bridge required by a dynamic language. In addition, because Dart allows things like widgets to be moved into the app, the need to go over a bridge is reduced.</p><h4>Preemptive scheduling, time slicing, and shared resources</h4><p>Most computer languages that support multiple concurrent execution threads (including Java, Kotlin, Objective-C, and Swift) use <a href="https://en.wikipedia.org/wiki/Preemption_(computing)">preemption</a> to switch between threads. Each thread is allocated a “slice” of time to execute, and if it exceeds its allocated time the thread is preempted using a context switch. However, if the preemption occurs when a resource that is shared between threads (like memory) is being updated, then this causes a <a href="https://en.wikipedia.org/wiki/Race_condition">race condition</a>.</p><p>Race conditions are a double whammy because they can cause serious bugs, including crashing your app and causing data to be lost, and they are particularly difficult to find and fix because they depend on the <a href="https://en.wikipedia.org/wiki/Race_condition#Software">relative timing of independent threads</a>. It is all too common for race conditions to stop manifesting themselves when you run the app in a debugger.</p><p>The typical way to fix a race condition is to protect the shared resource using <a href="https://en.wikipedia.org/wiki/Lock_(computer_science)">a lock</a> that prevents other threads from executing, but locks themselves can cause jank, or <a href="https://en.wikipedia.org/wiki/Dining_philosophers_problem">even more serious problems</a> (including <a href="https://en.wikipedia.org/wiki/Deadlock">deadlock</a> and <a href="https://en.wikipedia.org/wiki/Starvation_(computer_science)">starvation</a>).</p><p>Dart took a different approach to this problem. Threads in Dart, called <em>isolates</em>, do not share memory, which avoids the need for most locks. Isolates communicate by passing messages over channels, which is similar to <em>actors</em> in <a href="https://www.erlang.org/">Erlang</a> or <em>web workers</em> in JavaScript.</p><p>Dart, like JavaScript, is <a href="https://en.wikipedia.org/wiki/Thread_(computing)#Single_threading">single threaded</a>, which means it does not allow preemption at all. Instead, threads explicitly yield (using <a href="https://www.dartlang.org/tutorials/language/futures">async/await, Futures</a>, or <a href="https://www.dartlang.org/tutorials/language/streams">Streams</a>). This gives the developer more control over execution. Single threading helps the developer ensure that critical functions (including animations and transitions) are executed to completion, without preemption. This is often a big advantage not just for user interfaces, but for other client-server code.</p><p>Of course, if the developer forgets to yield control, this can delay other code from executing. However, we have found that forgetting to yield is usually much easier to find and fix than forgetting to lock (because race conditions are difficult to find).</p><h4>Allocation and garbage collection</h4><p>Another serious cause of jank is garbage collection. Indeed, this is just a special case of accessing a shared resource (memory), which in many languages requires the use of locks. But locks might <a href="https://en.wikipedia.org/wiki/Tracing_garbage_collection#Stop-the-world_vs._incremental_vs._concurrent">stop the entire app from running</a> while free memory is collected. However, Dart can perform garbage collection almost all of the time <em>without locks</em>.</p><p>Dart uses an advanced <a href="https://medium.com/flutter-io/flutter-dont-fear-the-garbage-collector-d69b3ff1ca30">generational garbage collection and allocation scheme</a>, which is particularly fast for allocating many short-lived objects (perfect for reactive user interfaces like Flutter that rebuild the immutable view tree for every frame). Dart can allocate an object with a single pointer bump (no lock required). Once again, this results in smooth scrolling and animation, without jank.</p><h3>Unified layout</h3><p>Another benefit of Dart is that Flutter doesn’t split layout between your program and an additional templating or layout language like JSX or XML, nor does it require separate visual layout tools. Here’s a simple Flutter view, written in Dart:</p><pre>new Center(child:<br>  new Column(children: [<br>    new Text(&#39;Hello, World!&#39;),<br>    new Icon(Icons.star, color: Colors.green),<br>  ])<br>)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/195/1*vEDegE4I9KLBAEX1bjDMbQ.png" /><figcaption>A view in Dart and what it produces</figcaption></figure><p>Note how easy it is to visualize the output this code produces (even if you have no experience with Dart).</p><p>Note that now that Flutter uses Dart 2, layout has become even simpler and clearer because the new keyword is optional, so static layouts can look even more like they are written in a declarative layout language, like this:</p><pre>Center(child:<br>  Column(children: [<br>    Text(&#39;Hello, World!&#39;),<br>    Icon(Icons.star, color: Colors.green),<br>  ])<br>)</pre><p>However, I know what you are probably thinking — how can the <em>lack</em> of specialized layout languages be called an <em>advantage</em>? But it is actually a game changer. Here’s what a developer wrote in an article titled “<a href="https://hackernoon.com/why-native-app-developers-should-take-a-serious-look-at-flutter-e97361a1c073">Why native app developers should take a serious look at Flutter</a>”.</p><blockquote>In Flutter, layouts are defined using Dart code only. There is no XML / templating language. There’s no visual designer/storyboarding tool either.</blockquote><blockquote>My hunch is, upon hearing this, a number of you might even cringe a little. Prima facie, that was my reaction too. Isn’t it easier to do layouts using a visual tool. Wouldn’t writing all kinds of constraint logic in code make things overly complicated?</blockquote><blockquote>The answer for me turned out to be <strong>no</strong>. And boy! what an eye opener it has been.</blockquote><p>The first part of the answer is the hot reload mentioned above.</p><blockquote>I can’t stress enough how this is light years ahead of Android’s Instant Run, or any similar solution. It just works, even on large non-trivial apps. And it is crazy fast. That’s the power of Dart for you.</blockquote><blockquote>In practice, that makes a visual editor interface redundant. I did not miss XCode’s rather nice auto layout <strong>at all</strong>.</blockquote><p>Dart creates terse and easy to understand layout, while the “crazy fast” hot reload lets you see the results instantly. And that includes the non-static parts of your layout.</p><blockquote>And as a result, I have been way more productive writing layouts in Flutter (Dart) than either Android/XCode. Once you get the hang of it (for me that meant a couple of weeks), there is a substantial overhead reduction because of very little context switching that is happening. One does not have to switch to a design mode, and pick a mouse and start clicking around. And then wondering if something has to be done programmatically, how to achieve that etc. Everything is programmatic. And the APIs are very well designed. It becomes intuitive soon and is much more powerful than the constructs offered by auto layout / layout XMLs.</blockquote><p>For example, here is a simple list layout that adds a divider (horizontal line) between every other item, defined programmatically:</p><pre>return new ListView.builder(itemBuilder: (context, i) {<br>  if (i.isOdd) return new Divider(); <br>  // rest of function<br>});</pre><p>In Flutter, all layout exists in one place, regardless of whether it is static layout or programmatic layout. And <a href="https://groups.google.com/forum/#!topic/flutter-dev/lKtTQ-45kc4">new Dart tools</a>, including the Flutter Inspector and the outline view (which take advantage of all layout being in one place) make complex, beautiful layouts even easier.</p><h3>Is Dart a proprietary language?</h3><p>No, Dart (like Flutter) is completely open source with a clean license, and is also an <a href="https://www.ecma-international.org/publications/standards/Ecma-408.htm">ECMA standard</a>. Dart is popular inside and outside of Google. Inside Google it is one of the fastest growing languages and is used by Adwords, Flutter, <a href="https://github.com/fuchsia-mirror">Fuchsia</a> and others; outside, the Dart repository has more than 100 external committers.</p><p>An even better indicator of the openness of Dart is the growth of the community outside of Google. For example, we are seeing a steady stream of articles and videos on Dart (including Flutter and AngularDart) from third parties, a few of which I’ve quoted in this article.</p><p>In addition to the external committers to Dart itself, there are over 3000 packages in the <a href="https://pub.dartlang.org/">public Dart package repository</a>, including libraries for Firebase, Redux, RxDart, internationalization, encryption, databases, routing, collections, and more.</p><h3>Will Dart programmers be easy to find?</h3><p>If not many programmers know Dart, will it be more difficult to find qualified programmers? Ironically, Dart makes it <em>easier</em> to find programmers because it is an incredibly quick language to learn. Programmers who already know languages like Java, JavaScript, Kotlin, C#, or Swift can start programming in Dart almost immediately. On top of that, hot reload encourages users to play with Dart and try new things, which makes learning Dart even faster and more pleasurable.</p><p>Here’s how one programmer put it in an article titled “<a href="https://codeburst.io/why-flutter-will-take-off-in-2018-bbd75f8741b0">Why Flutter Will Take Off in 2018</a>”:</p><blockquote><a href="https://www.dartlang.org/">Dart</a>, the language used to develop Flutter apps, is <strong>stupid-simple to learn</strong>. Google has experience in creating simple, well documented languages like Go, for example. So far, to me, Dart reminds me of Ruby and it’s a pleasure to learn. It’s also not only for mobile but <a href="https://webdev.dartlang.org/">for the web as well</a>.</blockquote><p>From another article about Flutter and Dart, titled “<a href="https://medium.com/@franzsilva/why-flutter-and-not-framework-x-or-better-yet-why-im-going-flutter-all-in-b484ecb25336">Why Flutter? and not framework X? or better yet why i’m Going Flutter all in.</a>”</p><blockquote>Flutter uses the Dart Language that was created by google also, to be honest i’m not a fan of strongly typed languages like C# or JAVA, but i don’t know why Dart’s way of writing code seems different. And i feel very comfortable writing it. Maybe because it’s very simple to learn, and very straightforward.</blockquote><p>Dart was specifically designed to be familiar and easy to learn, through extensive UX research and testing. For example, in the first half of 2017 the Flutter team did <a href="https://medium.com/google-design/how-i-do-developer-ux-at-google-b21646c2c4df">a UX study with eight developers</a>. We gave them a short introduction to Flutter, then turned them loose for an hour or so creating a simple view. All of the participants were able to start programming right away, even though they had never used Dart before. They were focused on writing reactive views, not the language. <a href="https://www.dartlang.org/guides/get-started">Dart just worked</a>.</p><p>At the end, one participant (who had progressed particularly far in the task) hadn’t mentioned anything about the language, so we asked them if they realized what language they were using. They didn’t know. The language <em>didn’t matter</em>; they were programming in Dart in minutes.</p><p>The hard part about learning a new system is typically not learning the language, it is learning all the libraries, frameworks, tools, patterns, and best practices for writing good code. And the Dart libraries and tools are exceptionally good and well documented. <a href="https://hn.svelte.technology/item/15416892">One article proclaims</a>, “As a bonus, they also keep tremendous care of their codebase and they have the best documentation I’ve ever seen.” What little effort is spent learning Dart is easily made up for by the savings in time learning the rest.</p><p>As direct evidence, a large project inside of Google wanted to port their mobile app to iOS. They were about to hire some iOS programmers but instead decided to try Flutter. They monitored how long it took to get developers up to speed on Flutter. Their results showed that a programmer could learn Dart <em>and</em> Flutter and become productive in three weeks. This compares to the five weeks they had previously observed to get programmers up to speed on Android alone (not to mention that they would have had to hire and train developers for iOS).</p><p>Finally, the article “<a href="https://medium.com/@matthew.smith_66715/why-we-chose-flutter-and-how-its-changed-our-company-for-the-better-271ddd25da60">Why we chose Flutter and how it’s changed our company for the better</a>” is from a company that moved their large enterprise application to Dart on all three platforms (iOS, Android, and web). Their conclusions:</p><blockquote>Much easier to hire. We now look to take the best candidate regardless if they are from Web, iOS or Android.</blockquote><blockquote>We have 3x the bandwidth now that all of our teams are consolidated on a single code base.</blockquote><blockquote>Knowledge sharing is at an all time high</blockquote><p>They were able to <em>triple their productivity</em> by using Dart and Flutter. This should be no surprise given what they were doing before. They, like many companies, were building separate apps for each platform (web, iOS and Android) utilizing <em>separate languages, tools, and programmers</em>. Switching to Dart meant that they no longer had to hire three different kinds of programmers. And it was easy for them to move their existing programmers to Dart.</p><p>They and others have found that once programmers start using Flutter, they often <a href="https://traversoft.com/2017/06/07/talk-on-dart-and-flutter/">fall in love with Dart</a>. They like the terseness of the language, and the lack of ceremony. They love <a href="https://medium.com/@lukeaf/flutter-doesnt-need-kotlin-or-anything-else-5773965d5905">language features</a> such as cascades, named parameters, async/await, and streams. And above all else, they love the features of Flutter (like hot reload) that are made possible by Dart, and the beautiful, performant apps Dart helps them build.</p><h3>Dart 2</h3><p>As this article is being published, <a href="https://www.dartlang.org/dart-2">Dart 2</a> is being released. Dart 2 is focused on <a href="https://medium.com/@asandholm/announcing-dart-2-80ba01f43b6">improving the experience of building client apps</a>, including developer velocity, improved developer tooling, and type safety. For example, Dart 2 features a <a href="http://papl.cs.brown.edu/2014/safety-soundness.html"><em>sound type system</em></a> and <a href="https://en.wikipedia.org/wiki/Type_inference"><em>type inferencing</em></a>.</p><p>Dart 2 also makes the new keyword optional. This means that it is possible to describe many Flutter views <em>without using any keywords at all</em>, making them less cluttered and easier to read. For example:</p><pre>Widget build(BuildContext context) =&gt;<br>  Center(child:<br>    Column(children: [<br>      Text(&#39;Hello, World!&#39;),<br>      Icon(Icons.star, color: Colors.green),<br>    ])<br>  )</pre><p>Dart 2 also uses type inferencing to make many uses of the const keyword optional by not requiring const to be specified redundantly inside of a const context. For example, the statement:</p><pre>const breakfast = {<br>   const Doughnuts(): const [const Cruller(), const BostonCream()], <br>};</pre><p>can now be replaced by this:</p><pre>const breakfast = {<br>   Doughnuts(): [Cruller(), BostonCream()],<br>};</pre><p>Because breakfast is const, everything else is inferred to be const as well.</p><h4>The secret is focus</h4><p>The improvements in Dart 2 are focused on optimizing client-side development. But Dart will still be a great language to build server-side, desktop, embedded systems, or other programs.</p><p>Focus is a <em>good thing</em>. Pretty much all enduring popular languages benefitted from being very focused. For example:</p><ul><li>C was a system programming language for writing operating systems and compilers. It became so much more.</li><li>Java was a language <a href="https://en.wikipedia.org/wiki/Java_(software_platform)#History">designed for embedded systems</a>.</li><li>JavaScript was a scripting language for web browsers (!).</li><li>Even much-maligned PHP succeeded because it was focused on writing Personal Home Pages (where it got its name).</li></ul><p>On the other hand, many languages have explicitly tried (and failed) to be completely general purpose, such as PL/1 and Ada, among others. The most common problem is that <em>without focus</em>, these languages became proverbial kitchen sinks.</p><p>Many of the features that make Dart a great client-side language also make it a better language for use server side. For example, the fact that Dart avoids preemptive multi-tasking gives it the same advantages as Node on the server, but with much better and safer typing.</p><p>The same thing goes for writing software for embedded systems. Dart’s ability to handle multiple concurrent inputs reliably is key here.</p><p>Finally, Dart’s success on the client will inevitably generate more interest in using it on the server — just like what happened with JavaScript and Node. Why force people to use two different languages to build client-server software?</p><h3>Conclusion</h3><p>This is an exciting time for Dart. People who use Dart love it, and the new features in Dart 2 make it an even more valuable addition to your arsenal of tools. If you have not used Dart, I hope this article has provided you with valuable information about what is new or different about Dart, and that you will give it — and Flutter — a try.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Fdde502%3Fas_embed%3Dtrue&amp;dntp=1&amp;url=https%3A%2F%2Fupscri.be%2Fdde502%2F&amp;image=https%3A%2F%2Fucarecdn.com%2F57662ddc-da7c-407b-afcb-cb45184b2705%2F&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/d25dd15e8727342107fbe0b6d67b030e/href">https://medium.com/media/d25dd15e8727342107fbe0b6d67b030e/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dd635a054ebf" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/why-flutter-uses-dart-dd635a054ebf">Why Flutter Uses Dart</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s Revolutionary about Flutter]]></title>
            <link>https://medium.com/hackernoon/whats-revolutionary-about-flutter-946915b09514?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/946915b09514</guid>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[dart]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Fri, 25 Aug 2017 09:30:16 GMT</pubDate>
            <atom:updated>2019-01-17T11:43:02.629Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-sa/4.0/</cc:license>
            <content:encoded><![CDATA[<h3>What is Flutter?</h3><p>The Flutter mobile app SDK is a new way to build <em>beautiful</em> native mobile apps that break away from the “cookie cutter” apps that have been so common in the past. People who try Flutter really like it; for example, see <a href="https://medium.com/@aubykhan/how-i-built-a-cross-platform-connected-app-in-7-days-93728a987424">this</a>, <a href="https://medium.com/@germansaprykin/flutter-first-steps-fffd906f093b">this</a>, or <a href="https://code.tutsplus.com/tutorials/developing-an-android-app-with-flutter--cms-28270">this</a>. Or here’s a <a href="https://github.com/Solido/awesome-flutter">list of articles and videos</a> compiled by a third party.</p><p>As with any new system, people want to know what makes Flutter different, or put another way, “what is new and exciting about Flutter?” That is a fair question, and this article will try to answer it from a technical viewpoint — not just <em>what</em> is exciting, but <em>why</em>.</p><p>But first, a little history.</p><h3>A brief history of mobile app development</h3><p>Mobile app development is a relatively recent field of endeavor. Third-party developers have been able to build mobile apps for less than a decade, so it is no surprise that tools are still evolving.</p><h4>The Platform SDKs</h4><p>The Apple iOS SDK was released in 2008 and the Google Android SDK in 2009. These two SDKs were based on different languages: Objective-C and Java, respectively.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/524/1*DXsvg0ir2nvYOTiUpp9KJw.png" /></figure><p>Your app talks to the platform to create widgets, or access services like the camera. The widgets are rendered to a screen canvas, and events are passed back to the widgets. This is a simple architecture, but you pretty much have to create separate apps for each platform because the widgets are different, not to mention the native languages.</p><h4>WebViews</h4><p>The first cross-platform frameworks were based on JavaScript and WebViews. Examples include a <a href="https://en.wikipedia.org/wiki/Apache_Cordova">family of related frameworks</a>: PhoneGap, Apache Cordova, Ionic, and others. Before Apple released their iOS SDK they encouraged third party developers to build webapps for the iPhone, so building cross-platform apps using web technologies was an obvious step.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/631/1*kxf6pHPvCeqmy-bdCqkHFA.png" /></figure><p>Your app creates HTML and displays it in a WebView on the platform. Note that it is difficult for languages like JavaScript to talk directly to native code (like the services) so they go through a “bridge” that does context switches between the JavaScript realm and the native realm. Because platform services are typically not called all that often, this did not cause too many performance problems.</p><h4>Reactive Views</h4><p>Reactive web frameworks like <a href="https://facebook.github.io/react/">ReactJS</a> (and <a href="https://github.com/Raynos/mercury">others</a>) have become popular, mainly because they simplify the creation of web views through the use of programming patterns borrowed from <a href="https://en.wikipedia.org/wiki/Reactive_programming">reactive programming</a>. In 2015, React Native was created to bring the many benefits of reactive-style views to mobile apps.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*8ugYUcmOYnoDx7d99qkEjQ.png" /></figure><p>React Native is very popular (and deserves to be), but because the JavaScript realm accesses the platform widgets in the native realm, it has to <a href="https://medium.com/@talkol/performance-limitations-of-react-native-and-how-to-overcome-them-947630d7f440">go through the bridge</a> for those as well. Widgets are typically accessed quite frequently (up to 60 times a second during animations, transitions, or when the user “swipes” something on the screen with their finger) so this can cause performance problems. As <a href="https://medium.com/@talkol/performance-limitations-of-react-native-and-how-to-overcome-them-947630d7f440">one article about React Native</a> puts it:</p><blockquote>Here lies one of the main keys to understanding React Native performance. Each realm by itself is blazingly fast. The performance bottleneck often occurs when we move from one realm to the other. In order to architect performant React Native apps, we must keep passes over the bridge to a minimum.</blockquote><h4>Flutter</h4><p>Like React Native, Flutter also provides reactive-style views. Flutter takes a different approach to avoiding performance problems caused by the need for a JavaScript bridge by using a compiled programming language, namely <a href="https://www.dartlang.org/">Dart</a>. Dart is compiled “ahead of time” (AOT) into native code for multiple platforms. This allows Flutter to communicate with the platform without going through a JavaScript bridge that does a context switch. Compiling to native code also improves app startup times.</p><p>The fact that Flutter is the only mobile SDK that provides reactive views without requiring a JavaScript bridge should be enough to make Flutter interesting and worth trying, but there is something <em>far more revolutionary</em> about Flutter, and that is how it implements <em>widgets</em>.</p><h3>Widgets</h3><p>Widgets are the elements that affect and control the view and interface to an app. It is not an overstatement to say that the widgets are one of the most important parts of a mobile app. In fact, widgets alone can <em>make</em> or <em>break</em> an app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/0*XaqUM2laHn4N9aGv." /></figure><ul><li>The <strong>look</strong> and <strong>feel</strong> of widgets is paramount. Widgets need to look good, including on various screen sizes. They also need to feel natural.</li><li>Widgets must perform <strong>fast</strong>:<strong> </strong>to create the widget tree, inflate the widgets (instantiating their children), lay them out on the screen, render them, or (especially) animate them.</li><li>For modern apps, widgets should be <strong>extensible </strong>and<strong> customizable</strong>. Developers want to be able to add delightful new widgets, and customize all widgets to match the app’s brand.</li></ul><p>Flutter has a new architecture that includes widgets that look and feel good, are fast, and are customizable and extensible. That’s right, Flutter does not use the platform widgets (or DOM WebViews), it provides its own widgets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/628/1*UpoHX3az39ZqkFwBr_gndA.png" /></figure><p>Flutter raises the widgets and renderer from the platform into the app, which allows them to be customizable and extensible. All that Flutter requires of the platform is a canvas in which to render the widgets so they can appear on the device screen, and access to events (touches, timers, etc.) and services (location, camera, etc.).</p><p>There is still an interface between the Dart program (in green) and the native platform code (in blue, for either iOS or Android) that does data encoding and decoding, but this can be orders of magnitude faster than a JavaScript bridge.</p><p>Moving the widgets and the renderer into the app does affect the size of the app. The minimum size of a Flutter app on Android is approximately 4.7MB, which is similar to minimal apps built with comparable tools. It is up to you to decide if the benefits of Flutter are worth any tradeoff, so the rest of this article discusses these benefits.</p><h3>Layout</h3><p>One of the biggest improvements in Flutter is how it does layout. <strong>Layout</strong> determines the size and position of widgets based on a set of rules (also called constraints).</p><p>Traditionally, layout uses a large set of rules that can be applied to (virtually) any widget. The rules implement multiple layout methods. Let’s take as an example CSS layout because it is well known (although layout in Android and iOS is basically similar). CSS has properties (the rules), which are applied to HTML elements (the widgets). CSS3 defines 375 properties.</p><p>CSS includes a number of layout models, including (multiple) box models, floating elements, tables, multiple columns of text, paged media, and so on. Additional layout models, like flexbox and grid, were added later because developers and designers needed more control over layout and were using tables and transparent images to get what they wanted. In traditional layout new layout models cannot be added by the developer, so flexbox and grid had to be added to CSS and implemented on all browsers.</p><p>Another problem with traditional layout is that the rules can interact (and even conflict) with each other, and elements often have dozens of rules applied to them. This makes layout slow. Even worse, layout performance is typically of order N-squared, so as the number of elements increases, layout slows down even more.</p><p>Flutter started as an experiment performed by members of the Chrome browser team at Google. We wanted to see if a faster renderer could be built if we ignored the traditional model of layout. After a few weeks, we had achieved significant performance gains. We discovered:</p><ul><li>Most layout is relatively simple, such as: text on a scrolling page, fixed rectangles whose size and position depend only on the size of the display, and maybe some tables, floating elements, etc.</li><li>Most layout is local to a subtree of widgets, and that subtree typically uses one layout model, so only a small number of rules need to be supported by those widgets.</li></ul><p>We realized that layout could be simplified significantly if we <em>turned it on its head</em>:</p><ul><li>Instead of having a large set of layout rules that could be applied to any widget, each widget would specify its own simple layout model.</li><li>Because each widget has a much smaller set of layout rules to consider, layout can be optimized heavily.</li><li>To simplify layout even further, we turned almost everything into a widget.</li></ul><p>Here’s Flutter code to create a simple widget tree with layout:</p><pre>new Center(<br>  child: new Column(<br>    children: [<br>      new Text(&#39;Hello, World!&#39;)),<br>      new Icon(Icons.star, color: Colors.green)<br>    ]<br>  )<br>)</pre><p>This code is semantic enough that you can easily imagine what it will produce, but here’s the resulting display:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/195/0*zfqFQH9aWZDc2oqf." /></figure><p>In this code <a href="https://flutter.io/widgets/">everything is a widget</a>, including the layout. The Center widget centers its child inside its parent (for example, the screen). The Column layout widget arranges its children (a list of widgets) vertically. The column contains a Text widget and an Icon widget (which does have a property, its color).</p><p>In Flutter, centering and padding are widgets. Themes are widgets, which apply to their children. And even applications and navigation are widgets.</p><p>Flutter includes quite a few widgets for doing layout, not just columns but also rows, grids, lists, etc. In addition, Flutter has a unique layout model we call the “sliver layout model” which is used for scrolling. Layout in Flutter is so fast it can be used for scrolling. Think about that for a moment. Scrolling must be so instantaneous and smooth that the user feels like the screen image is attached to their finger as they drag it across the physical screen.</p><p>By using layout for scrolling, Flutter can implement advanced kinds of scrolling, like these shown below. Note that these are animated GIF images, Flutter is even smoother. You can (and should!) run these apps yourself; see the Resources section at the end of this article.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*ixLiB5aU96pKsPiZBhmuMQ.gif" /><figcaption>Flutter Gallery app</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*0wUIUYFYxVBrz-fzhdO88g.gif" /><figcaption>Posse Gallery app</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*o-KbeRBGYA7Tz_WwoUP2uQ.gif" /><figcaption>Posse Gallery app</figcaption></figure><p>Most of the time, Flutter can do layout in a single pass, which means in linear time, so it can handle large numbers of widgets. Flutter also does caching and other things so it can avoid doing layout at all, when possible.</p><h3>Custom design</h3><p>Because widgets are now part of the app, new widgets can be added and existing widgets can be customized to give them a different look or feel, or to match a company’s brand. The trend in mobile design is away from the cookie cutter apps that were common a few years ago and toward custom designs that delight users and win awards.</p><p>Flutter comes with rich, customizable widget sets for Android, <a href="https://flutter.io/widgets/cupertino/">iOS</a>, and <a href="https://material.io/">Material Design</a> (in fact, we have been told that Flutter has one of the highest fidelity implementations of Material Design). We used the customizability of Flutter to build these widget sets, to match the look and feel of native widgets on multiple platforms. App developers can use the same customizability to further tweak widgets to their wants and needs.</p><h3>More about Reactive Views</h3><p>Libraries for reactive web views introduced <strong>virtual DOM</strong>. DOM is the HTML Document Object Model, an API used by JavaScript to manipulate an HTML document, represented as a tree of elements. Virtual DOM is an abstract version of the DOM created using objects in the programming language, in this case JavaScript.</p><p>In reactive web views (implemented by systems like <a href="https://facebook.github.io/react/">ReactJS</a> and others) the virtual DOM is immutable, and is rebuilt from scratch each time anything changes. The virtual DOM is compared to the real DOM to generate a set of minimal changes, which are then executed to update the real DOM. Finally, the platform re-renders the real DOM and paints it into a canvas.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/661/1*X6yx8C1XXDEVw9YZY3V1hQ.png" /></figure><p>This may sound like an awful lot of extra work, but it is well worth it because <a href="https://www.codecademy.com/articles/react-virtual-dom">manipulating the HTML DOM is very expensive</a>.</p><p>React Native does a similar thing, but for mobile apps. Instead of DOM, it manipulates the native widgets on the mobile platform. Instead of a virtual DOM, It builds a virtual tree of widgets and compares it to the native widgets and only updates those that have changed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/656/1*ifXMfvs2mIh0n8qtftxC0A.png" /></figure><p>Remember that React Native has to communicate with the native widgets through the bridge, so the virtual tree of widgets helps keep passes over the bridge to a minimum, while still allowing the use of native widgets. Finally, once the native widgets are updated, the platform then renders them to the canvas.</p><p>React Native is a big win for mobile development, and was an inspiration for Flutter, but Flutter takes this a step further.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/342/1*iHg6NkSFGqA-0If6lg_PLA.png" /></figure><p>Recall that in Flutter, the widgets and the renderer have been lifted up out of the platform into the user’s app. There are no native platform widgets to manipulate, so what was a virtual widget tree is now <em>the</em> widget tree. Flutter renders the widget tree and paints it to a platform canvas. This is nice and simple (and fast). In addition, animation happens in user space, so the app (and thus the developer) have more control over it.</p><p>The Flutter renderer itself is interesting: it uses several internal tree structures to render only those widgets that need to be updated on the screen. For example, the renderer uses “<a href="https://youtu.be/UUfXWzp0-DU">structural repainting using compositing</a>” (“structural” meaning <em>by widget</em>, which is more efficient than doing it by rectangular areas on the screen). Unchanged widgets, even those that have moved, are “<a href="https://en.wikipedia.org/wiki/Bit_blit">bit blitted</a>” from cache, which is super fast. This is one of the things that makes scrolling so performant in Flutter, even in advanced scrolling (discussed and shown above).</p><p>For a closer look at the Flutter renderer, I <a href="https://youtu.be/UUfXWzp0-DU">recommend this video</a>. You can also look at the code, because <a href="https://github.com/flutter">Flutter is open source</a>. And of course, you can customize or even replace the whole stack, including the renderer, compositor, animation, gesture recognizer, and (of course) the widgets.</p><h3>The Dart programming language</h3><p>Because Flutter — like other systems that use reactive views — refreshes the view tree for every new frame, it creates many objects that may live for only one frame (a sixtieth of a second). Fortunately, Dart uses “<a href="https://en.wikipedia.org/wiki/Tracing_garbage_collection#Generational_GC_.28ephemeral_GC.29">generational garbage collection</a>” that is very efficient for these kind of systems, because objects (especially short-lived ones) are relatively cheap. In addition, allocation of objects can be done with a single pointer bump, which is fast and doesn’t require locks. This helps avoid UI <a href="https://en.wiktionary.org/wiki/jank">jank</a> and stutter.</p><p>Dart also has a “<a href="https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80">tree shaking</a>” compiler, which only includes code that you need in your app. You can feel free to use a large library of widgets even if you only need one or two of them.</p><p>For more information about Dart, read “<a href="https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf">Why Flutter uses Dart</a>”.</p><h3>Hot reload</h3><p>One of the most popular features of Flutter is its fast, stateful hot reload. You can make a change to a Flutter app while it is running, and it will reload the app’s code that has changed and let it continue from where it left off, often in less than a second. If your app encounters an error, you can typically fix the error and then continue on as if the error never happened. Even when you have to do a full reload, it is fast.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/864/1*oE-etcL1SzjYrNWTac9RtQ.gif" /><figcaption>hot stateful reload</figcaption></figure><p>Developers tell us that this lets them “paint” their app, making one change at a time and then seeing the results almost instantly, without having to restart the app.</p><h3>Compatibility</h3><p>Because widgets (and the renderer for those widgets) are part of your app, not the platform, no “<a href="https://developer.android.com/topic/libraries/support-library/index.html">compat libraries</a>” are needed. Your apps will not only work, but they will work the same on recent OS versions — Android Jelly Bean and newer and iOS 8.0 and newer. This significantly reduces the need to test apps on older OS versions. Plus it is likely that your apps will work on future OS versions.</p><p>There is one potential concern that we get asked about. Because Flutter doesn’t use the native platform widgets, will it take long for the Flutter widgets to be updated when a new version of iOS or Android comes out that supports a new kind of widget, or changes the look or behavior of an existing widget?</p><ul><li>First of all, Google is a big internal user of Flutter, so we have a strong incentive to update the widget sets to keep them current and as close to the current platform widgets as possible.</li><li>If there is ever a time when we are too slow in updating a widget, Google isn’t the only user of Flutter with an incentive to keep the widgets current. Flutter’s widgets are so extensible and customizable that anyone can update them, even you. One doesn’t even have to file a pull request. You will never have to wait for Flutter itself to be updated.</li><li>And the above points apply only if you want to have the new change reflected in your app. If you <em>don’t</em> want a change to affect the way your app looks or behaves, you’re good. Widgets are part of your app, so a widget will never change out from under you and make your app look bad (or worse, break your app).</li><li>As an added benefit, you can write your app so it uses the new widget even on older OS versions.</li></ul><h3>Other benefits</h3><p>Flutter’s simplicity makes it fast, but it is the pervasive customizability and extensibility that makes it powerful.</p><p>Dart has a <a href="https://pub.dartlang.org/flutter/packages/">repository of software packages</a> so you can extend the capabilities of your apps. For example, there are a number of packages that make it easy to <a href="https://github.com/flutter/plugins/blob/master/FlutterFire.md">access Firebase</a> so you can build a “serverless” app. An outside contributor has created a package that lets you access a <a href="https://pub.dartlang.org/packages/flutter_built_redux">Redux data store</a>. There are also packages called “<a href="https://flutter.io/developing-packages/">plugins</a>” that make it easier to access platform services and hardware, such as the accelerometer or the camera, in an OS-independent way.</p><p>Of course, Flutter is also <a href="https://github.com/flutter">open source</a>, which coupled with the fact that the Flutter rendering stack is part of your app, means that you can customize almost anything you want for an individual app. Everything in green in this figure can be customized:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*NeeJq8PwkiTj8eMf." /></figure><h3>So, “What’s new and exciting about Flutter?”</h3><p>If anyone asks you about Flutter, now you know how to answer them:</p><ul><li>The advantages of reactive views, with no JavaScript bridge</li><li>Fast, smooth, and predictable; code compiles AOT to native (ARM) code</li><li>The developer has full control over the widgets and layout</li><li>Comes with beautiful, customizable widgets</li><li>Great developer tools, with amazing hot reload</li><li>More performant, more compatibility, more fun</li></ul><p>Did you notice what I left off this list? It is something that is usually the first thing people mention when they talk about Flutter, but to me it is one of the least interesting things about Flutter.</p><p>It is the fact that Flutter can build beautiful and fast apps for multiple platforms from a single codebase. Of course, that should be a given! It is customizability and extensibility that makes it easy to target Flutter to multiple platforms without giving up performance or power.</p><h3>Revolutionary</h3><p>I also never fully explained why Flutter is “revolutionary”. It just seems fitting, because one of the <a href="https://blog.goposse.com/a-revolutionary-app-for-a-revolutionary-show-1b687f24023b">first major apps built with Flutter by outside developers</a> is the official app for “<a href="http://www.hamiltonbroadway.com/">Hamilton: An American Musical</a>”, which takes place around the time of the American Revolutionary War. <a href="http://www.cnn.com/2017/08/14/entertainment/hamilton-app/index.html">Hamilton is one of the most popular</a> Broadway musicals of all time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/1*x1B9LpfaDlYra56L5PsRSw.png" /></figure><p>The agency, <a href="http://goposse.com/">Posse</a>, says they picked Flutter because they needed to build the app “<a href="https://developers.googleblog.com/2017/08/hamilton-app-takes-stage.html">in only three short months</a>”. They call it “A revolutionary app for a revolutionary show” and say “Flutter is an excellent choice for beautiful, high-performance, brand-driven mobile experiences.” <a href="https://youtu.be/prlK_QL_qOA">They also gave a talk</a> at the Google Developer Days conference on their experience building an app with Flutter. The app is available on <a href="https://play.google.com/store/apps/details?id=com.hamilton.app">Android</a> and <a href="https://itunes.apple.com/us/app/hamilton-the-official-app/id1255231054">iOS</a>, and <a href="http://www.cnn.com/2017/08/14/entertainment/hamilton-app/index.html">received rave reviews</a>.</p><h3>Join the Revolution!</h3><p>On December 4, 2018, <a href="https://developers.google.com/events/flutter-live/">Flutter 1.0 was released</a>. We will continue to add more features to it, and we have more optimizations planned. Use of Flutter has taken off, with <a href="https://medium.com/flutter-io/flutter-live-wrapup-57c535ef8994">more than 250,000 developers</a> around the world. Flutter is currently in the top 20 on Github for active software repositories.</p><p>If you are interested in Flutter, <a href="https://flutter.io/setup/">you can install it</a> and <a href="https://flutter.io/getting-started/">play around with</a> some sample apps that come with the installation. Be sure to check out the stateful hot reload.</p><p>If you aren’t a developer or just want to see some apps, you can install apps built with Flutter and see how they look and perform. I recommend the <a href="http://www.hamiltonbroadway.com/#newyork-app">Hamilton app</a>, but there are others. You should also watch the <a href="https://goo.gl/csEr1f">video from Google I/O</a> where they live code a Flutter app.</p><h3>Resources</h3><ul><li>Watch the <a href="https://www.youtube.com/results?search_query=io2018+flutter">Flutter videos from Google I/O 2018</a></li><li>Watch the <a href="https://www.youtube.com/results?search_query=DartConf+2018">videos from DartConf 2018</a>, held January 23–24, 2018 in Los Angeles, California</li><li><a href="https://youtu.be/fq4N0hgOWzU">Introducing Flutter video</a>.</li></ul><h4>Websites:</h4><ul><li>The <a href="https://flutter.io/">Flutter website</a></li><li>The <a href="https://github.com/flutter/flutter">source repositories</a> (pull requests welcome!)</li><li><a href="https://github.com/Solido/awesome-flutter">More helpful links</a></li><li><a href="https://gitter.im/flutter/flutter">Gitter channel</a></li></ul><h4>Videos:</h4><ul><li><a href="https://youtu.be/prlK_QL_qOA">Experience building the Hamilton app, at GDD</a></li><li><a href="https://goo.gl/csEr1f">Live coding a Flutter app, at Google I/O</a></li><li><a href="https://goo.gl/N29fiK">Live coding with a designer, at Google I/O</a></li><li>“<a href="https://goo.gl/g1tDQR">Flutter, a new hope</a>” at Droidcon Italy</li><li>“<a href="https://goo.gl/RH3N4Y">The Flutter rendering pipeline</a>”</li></ul><h4>Apps:</h4><ul><li>The app for <a href="http://www.hamiltonbroadway.com/#newyork-app">Hamilton: An American Musical</a></li><li>Flutter Gallery: <a href="https://play.google.com/store/apps/details?id=io.flutter.gallery">for Android</a>, <a href="https://github.com/flutter/flutter/tree/master/examples/flutter_gallery">on Github</a> (also included in the flutter install at examples/flutter_gallery)</li><li><a href="https://github.com/flutter/posse_gallery">Posse Gallery</a></li><li>Friendlychat: <a href="https://codelabs.developers.google.com/codelabs/flutter/index.html">first codelab</a>, <a href="https://codelabs.developers.google.com/codelabs/flutter-firebase/index.html">Firebase codelab</a>, <a href="https://github.com/flutter/friendlychat-steps">on Github</a></li></ul><h4>Further reading:</h4><ul><li><a href="https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf">Why Flutter uses Dart</a></li><li><a href="https://medium.com/flutter-io/pitching-flutter-to-your-company-or-client-2d4f494e47d1">Pitching Flutter to your company or client</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=946915b09514" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/whats-revolutionary-about-flutter-946915b09514">What’s Revolutionary about Flutter</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Best Display for Programming?]]></title>
            <link>https://medium.com/hackernoon/the-best-display-for-programming-8aad0be4227d?source=rss-64fb7daa2629------2</link>
            <guid isPermaLink="false">https://medium.com/p/8aad0be4227d</guid>
            <category><![CDATA[display]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[productivity]]></category>
            <dc:creator><![CDATA[Wm Leler]]></dc:creator>
            <pubDate>Fri, 07 Jul 2017 23:46:32 GMT</pubDate>
            <atom:updated>2017-07-08T03:11:43.591Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CRdUeifAKg9-ugr6KOk6fw.jpeg" /><figcaption><strong>My new work monitor.</strong></figcaption></figure><p>[If you’re the kind of person who loves programming on your smallish laptop, you can stop reading now.]</p><p>If you are a software developer and you’re like me, you may find that you are far more productive when you have enough real estate. I’m not talking about cubicle space, I’m talking about <em>screen</em> real estate: large monitors and usually more than one of ’em (at least until now).</p><p>I own three 30-inch Apple Cinema displays, but I typically used only two of them on a single computer (most laptops can only drive two of them at once; some can only drive a single monitor).</p><p>When 4K monitors came out I was intrigued. When they came down in price I was excited. And when my wife and I moved into a one-room condo downtown and realized that we had to significantly downsize, I had an idea: get a single 4K monitor and use it instead of multiple monitors (and use it for watching movies too, so we wouldn’t need a separate TV).</p><p>I liked the resolution of the 30-inch monitors, which is 2560 by 1600 pixels. That is 100.63 pixels per inch (PPI). For programming I didn’t care about having a high pixel density (like <a href="https://en.wikipedia.org/wiki/Retina_Display">Retina displays</a> do, which have a device pixel ratio greater than one). I wanted <em>more</em> text characters, not slightly smoother looking ones. A 4K display has a resolution of 3840 by 2160, more than the number of pixels on two 30-inch monitors. My question was, in order to ensure that the pixels would have the same PPI, what size 4K monitor should I buy?</p><h3>43-inch monitors</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/652/1*oOKU1yXPfO9iIlVnJ3KpwA.png" /><figcaption><strong>30 vs 43 inches — more than twice as many pixels</strong></figcaption></figure><p>I calculated that the proper size for a 4K monitor was around 43 inches (diagonal). I quickly found one, the Dell P4317Q, and it had a reasonable price and good reviews. It has a TFT active matrix panel that looks really sharp with good color. Despite being called a 43-inch monitor it is actually 42.5 inches, so it has 103.7 PPI, but that difference is negligible (and I think I actually like the slightly smaller physical size better).</p><p>I had been worried that a 43-inch monitor might feel too huge. I used to own a 42-inch 1080p HDTV set (we gave it away before moving into the condo). I couldn’t imagine sitting close enough to use it as a monitor, however at 4K resolution a monitor that size is fine.</p><p>My 43-inch monitor is around 70% of the physical width of two 30-inch monitors placed side-by-side, so it takes up less desk space (which is important on my new, smaller desk). And my eyes don’t have to move left or right as far anymore.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BeT8kuzlOfbAHky0nXzSow.jpeg" /><figcaption><strong>My home setup: one 43-inch monitor, two laptops, and a KVM.</strong></figcaption></figure><p>I quickly found other advantages to this setup. The MacOS feature of having multiple desktop spaces became easier to use with a single large monitor. I can put my social media pages in a separate space so they don’t distract me while I’m working.</p><p>The only thing I don’t like about the Dell monitor are that its HDMI inputs are version 1.4, which can only do a 30Hz refresh rate at full resolution. But it also has DisplayPort inputs, which can do 60Hz, so I use DisplayPort (or mini-DisplayPort) to connect to my computer. DisplayPort and mini-DisplayPort are well supported on Apple, Windows, and Linux computers.</p><p>The next problem was that I liked it so much that I wanted the same setup at work (where I still used two 30-inch monitors). Just about that time, Viewsonic came out with a very similar monitor, the VX4380 (in fact, so similar that I believe it uses the same panel). So I bought one of those too.</p><p>How do these two monitors compare?</p><ul><li>The Viewsonic has the advantage that it has HDMI 2.0 inputs instead of 1.4, so it can use the HDMI inputs at 60Hz. It is also cheaper and I like its menu system better, although its control buttons are inconveniently located on the back of the monitor instead of the front.</li><li>The Dell is more expensive, but it feels better built, with a nicer stand with more adjustments and some cable routing.</li></ul><p>Both have four inputs: two DisplayPort and two HDMI. Both are excellent monitors. In fact, both are pretty much <em>perfect</em>!</p><p>I’ve been using them for a few months, and I like using one 43-inch 4K monitor far better than using two 30-inch monitors. As a programmer, I can have a large IDE window, program output, debugging window, github, gitter, terminals, logs, multiple documentation windows, and various other windows open and usable at all times. If I need to edit a large diagram or photograph I can really enlarge it without having to stretch it across multiple monitors.</p><p>And through the miracle of mass production for the consumer 4K TV market, you’ll probably pay less for a 4K monitor than if you bought a <em>single</em> 30-inch monitor with a resolution of 2560 by 1600 (let alone two).</p><p>By the time you read this, there might be other 43-inch 4K monitors available. You should check them out too. I just noticed the LG 43UD79-B, which even has a USB-C video input (Thunderbolt 3 or DisplayPort over USB-C) , but I haven’t tried it. It too appears to use the same panel as the Dell and Viewsonic monitors.</p><p>If you are looking at other monitors, note that I would avoid buying a display sold mainly for home viewing of TV and movies. They usually don’t have the inputs you want, and are usually less sharp because you don’t typically sit two feet away from them. You may pay slightly more for a real computer monitor, but it is worth it. As a bonus, a large computer monitor will work great for watching movies (although depending on the monitor, you may need to get some good self-powered speakers). If you want to watch TV you will need to plug it into a cable box or a streaming box of some kind (HDMI inputs will come in handy for that).</p><h3>Setup</h3><p>Your computer must be able to drive the required resolution and scan rate (3840 by 2160 at 60Hz). In fact, I had to upgrade one of my work computers (a 2014 MacBook Air; my employer traded it for a used 2015 one that works fine). Your computer’s video connectors should be:</p><ul><li>DisplayPort (mini or regular, at least version 1.2),</li><li>HDMI (at least version 2.0), or</li><li>the new USB-C video (Thunderbolt 3 or DisplayPort over USB-C), which provides a DisplayPort 1.2 signal.</li></ul><p>I’ve seen a couple of cases on the internet where people could not get a 4K monitor to work, even though the computer should have been able to drive it. According to them, the problem turned out to be old or bad cables. Unfortunately, most monitor cables are not labeled so it is difficult to know if they are the proper DisplayPort 1.2 or HDMI 2.0 (or higher). If you have problems, trying buying a new cable of the right version. One person I read about even found that the cable that came with their monitor was the wrong version, and wouldn’t work at 60Hz. And don’t even think about using DVI or VGA.</p><p>Finally, keep the number of adapters between your computer and monitor to a minimum: a single cable with no adapters if possible. My work computer has Thunderbolt 3 with USB-C connectors for video (the new Apple standard), so I bought a USB-C to DisplayPort cable. My home computer is mini-DisplayPort (the old Apple standard), so I use a mini-DisplayPort to DisplayPort cable. Both work great, which should be no surprise because the Thunderbolt 3 video signal is the same as DisplayPort, and mini-DisplayPort is just a smaller connector for DisplayPort.</p><p>I also bought a DisplayPort KVM so I can use one keyboard, video (monitor), and mouse with two different computers. It works fine with two computers that have mini-DisplayPort outputs, but when I tried to use it with my computer that has Thunderbolt 3 (USB-C) output, it would not work. Apparently, having a Thunderbolt 3 to mini-DisplayPort adapter followed by the KVM was just too much. My workaround was to use a USB-C to DisplayPort cable, skip the KVM and plug it directly into a separate input on the monitor. If anyone has figured out how to use a KVM with Thunderbolt 3, let me know in the comments.</p><p><strong>tl;dr</strong> 43-inch 4K computer monitors should be the <em>new hotness</em> for people who like big monitors. And they should work well with almost any computer made in the last couple of years, as long as you use the proper cables.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8aad0be4227d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/the-best-display-for-programming-8aad0be4227d">The Best Display for Programming?</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>