<?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"><channel><title><![CDATA[劉庭均 LiuTingChun]]></title><description><![CDATA[劉庭均 個人網頁 Liu Ting Chun personal website ]]></description><link>https://www.liutingchun.com/blog</link><generator>RSS for Node</generator><lastBuildDate>Sun, 07 Jan 2024 22:42:07 GMT</lastBuildDate><atom:link href="https://www.liutingchun.com/blog-feed.xml" rel="self" type="application/rss+xml"/><item><title><![CDATA[藝術學院的基礎爬說分享（待完善）]]></title><description><![CDATA[這學期算是比較正式接了助教，想説寫給自己整理也分享這學期的課程大綱，還有一些自己的雜談與碎念。 工作室開的課程，無論是實務課程或理論課程一直以來都是以電腦文學和自然語言處理作為討論基礎。在這邊對於電腦文學的討論，源自於希臘哲學中的...]]></description><link>https://www.liutingchun.com/post/pythonintroduction</link><guid isPermaLink="false">638dec079b86531dd1ede499</guid><category><![CDATA[technique]]></category><pubDate>Mon, 05 Dec 2022 16:45:25 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_52c491c8438c43fea253894252aa5a6e~mv2.jpeg/v1/fit/w_792,h_495,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<figure><img src="https://static.wixstatic.com/media/4eb1dd_52c491c8438c43fea253894252aa5a6e~mv2.jpeg/v1/fit/w_792,h_495,al_c,q_80/file.png"  ></figure><p>這學期算是比較正式接了助教，想説寫給自己整理也分享這學期的課程大綱，還有一些自己的雜談與碎念。</p>

<p><a href="https://ground-zero.khm.de/" target="_blank" ><u>工作室</u></a>開的課程，無論是實務課程或理論課程一直以來都是以電腦文學和自然語言處理作為討論基礎。在這邊對於電腦文學的討論，源自於希臘哲學中的 <em>Poiesis</em>，意指為創造的過程與行為，在詞源上也與詩 Poetry 同源。因此導向了無論是程式語言本身作為詩的表現形式、亦或是以程式語言生產與分析文學的方向。往年也試著開過LSTM、<a href="https://github.com/experimental-informatics/hands-on-text-generators" target="_blank" ><u>馬可夫鏈</u></a>、<a href="https://github.com/experimental-informatics/hands-on-artificial-neural-networks" target="_blank" ><u>基礎神經網絡</u></a>、<a href="https://github.com/experimental-informatics/codichte_experiments-with-cognitive-systems" target="_blank" ><u>認知系統與電腦詩</u></a>等課程。從 GPT-2 延伸的 aitextgen, ai dungeon、Dall-E 1等等都曾經被納入討論。這學期是這幾年來第一次花一整學期走完程式設計基礎的課程。</p>

<p>教授很喜歡以1941年阿根廷作家 Jorge Luis Borges 的《<a href="https://www.libraryofbabel.info/" target="_blank" ><u>巴別塔圖書館</u></a>》(Library of Babel)作為課程的起點，想像一種基於無限遞迴的結構便能窮盡宇宙中所有基於拉丁文字的詩。以此開啟關於程式語言的想像。無論是 Joseph Weizenbaum 的 Eiza 和 Hans Magnus Enzensberger 的 Landsberger Poesieautomat (詩的販賣機) <a href="https://www.youtube.com/watch?v=vj1buZhKKko" target="_blank" ><u>2006年重現的裝置版</u></a>，作為德文一脈關於自然語言處理以降的彙整與推進，也算是老教授在退休前希望著重的方向吧。</p>

<p>在這幾年舉凡 GPT-3、Stable Diffusion、Midjourney 等等 Transformer Model 百花齊放之下，文字再度成為人工智慧發展的重點關注對象。剛好也結合學校文學組的課程，自然語言處理基礎便成為了學校架構基礎程式設計課程的主要方向。也只有在實際走過文字處理發展的歷史，才能更加深刻的操作與理解當代複雜人工智慧背後所影射的社會偏見。</p>

<p>底下變成課程的大綱，想找時間更詳細的補完所有內容，也算是給自己的整理。有趣的地方去年我們還在 GPT-2 的 AItextgen中玩耍（曾經我們很堅持使用 common crawl 的模型，但open ai 實在碾壓了眾生），才剛過一年到現在 ChatGPT 的發表，語言模型推層出新的同時，課程也不斷在被修正與修改。某種程度上，老教授也堅信只有無論技術或是理論的基礎打實，才能更加理解而非浪漫化這波浪潮。</p>

<p>小小的disclaimer是我知道正常的CS包含基礎程式設計和DSA甚至是ADA都是要花一年要兩年，但因為課綱的關係我們全部塞進一學期裡頭，也算是很概述的「介紹」程式設計。很多實務的部分還是看學生自己想進行的計畫再來進行修正</p>

<p>課程簡介：</p>
<p>在日益媒體化的社會中，演算法與程式設計的基本理解是數字自決 (Digital Self-determination)的核心關鍵。數位資訊和通訊系統主導著我們對生活現實和媒體自我形象的感知。更關鍵的是，我們正在透過演算法產生全新的體驗、行動和決策空間。 人工智慧也已在創作音樂、互動視覺和詩歌創作中使用。 因此，我們必須將分析和生成式演算法理解為一種基本的文化技術，其危險和美學層面必須以同樣的方式暴露出來。</p>

<p>這堂課程將教授以 Python 程式語言為基礎的技術和藝術實踐，並以文本生成作為核心方法。除了在簡單的開發環境中討論如何學習程式設計基礎，更重要的是將程式設計作為一種藝術乃至於社會實踐。然而，課程只能幫助克服第一道障礙，只有當掌握一定程度的技術，程式語言將不再是單純的功能問題，而是探索美學潛力的問題時，程式碼才能成為自身的藝術簽名。乃至於進一步理解與分析大規模演算法所帶來的社會現象、演算法偏見(Algorithmic Bias)等等問題意識。生成過程是關於自由與控制之間的平衡。我在哪裡可以放棄控制而創造驚喜，在哪裏又要保留控制以達到某種美感結果？</p>

<p>課程內容全部放置於 Github 頁面中：</p>
<p><a href="https://github.com/experimental-informatics/plunging-into-code" target="_blank" ><u>https://github.com/experimental-informatics/plunging-into-code</u></a> </p>

<p>教學環境：</p>
<p>程式設計介面為透過 <a href="https://jupyter.org/hub" target="_blank" ><u>Jupyter hub</u></a> 架設 Python Notebook 伺服器，環境控制為 <a href="https://docs.conda.io/en/latest/miniconda.html" target="_blank" ><u>mini conda</u></a>，檔案皆為 .ipynb。進階內容則建議自行安裝包含 GUI 的 <a href="https://anaconda.org/anaconda/anaconda-navigator" target="_blank" ><u>Anaconda-Navigator</u></a> </p>

<p>使用資料庫：</p>
<p><a href="https://pypi.org/project/openai/" target="_blank" ><u>openai</u></a>, <a href="https://pypi.org/project/requests/" target="_blank" ><u>requests</u></a>, <a href="https://pypi.org/project/nltk/" target="_blank" ><u>nltk</u></a>,  <a href="https://pypi.org/project/numpy/" target="_blank" ><u>numpy</u></a>, <a href="https://pypi.org/project/pandas/" target="_blank" ><u>pandas</u></a>, <a href="https://pypi.org/project/Wikipedia-API/" target="_blank" ><u>Wikipedia-API</u></a>, <a href="https://pypi.org/project/markovify/" target="_blank" ><u>markovify</u></a> </p>

<p>課綱設計原則：</p>
<p>原則上以上半節課講授程式相關內容，包含程式設計藝術家，電腦文學、人工智慧歷史，技術哲學、線上資料庫、演算法與資料偏見相關的文獻與論文。下半節課進行實務操作。</p>

<p>內容設計的分配原則上是我（基礎程式、資料結構）、博士生（資訊社會學、資料偏見與對抗式攻擊）、技工（電子控制與樹莓派）和教授（電腦文學、人工智慧史、技術哲學）之間的拔河，上課的時候會互相插播討論。因為希望所有內容都基於 Python 上讓學生不至於切換語言而感到混亂，所以共識是環繞文字處理與電腦文學為核心發展出來的。因為還是第一學期這樣執行，所以內容還十分混亂，應該明年會繼續整合和優化吧。</p>

<p>第一週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week1-Prompting" target="_blank" ><u>Prompt Design 作為與電腦互動的基礎</u></a> </p><ul>
  <li>Demo 自動化的 Prompt Design，來理解現今許多GPT-3相關軟體的基礎運作邏輯。</li>
</ul><p>第二週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week2-PythonEinf%C3%BChrung01" target="_blank" ><u>基礎 Python（一）- 環境介紹｜變數、資料型態、字串</u></a> </p><ul>
  <li>介紹 Jupyter Hub 作為環境基礎，盡量讓所有人使用瀏覽器編寫程式以避免太多的環境安裝問題。</li>
</ul><p>第三週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week3-PythonEinf%C3%BChrung02" target="_blank" ><u>基礎 Python（二）- 藝術家介紹 ｜陣列、列表、檔案讀取</u></a> </p><ul>
  <li>以一些電腦文字或是人工智慧相關的藝術家作為開端，帶學生想像可能的創作方向，乃至於對於人工智慧的社會批判現況。</li>
</ul><p>第四週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week4-PythonEinf%C3%BChrung03" target="_blank" ><u>基礎 Python（三）- 字串處理、迴圈、排序</u></a> </p><ul>
  <li>以排序演算法作為理解經典演算法運作的原理</li>
</ul><p>第五週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week5-DatasetEinf%C3%BChrung" target="_blank" ><u>資料庫基礎 - 線上資料庫與其偏見｜資料交換格式 - txt, Json, CSV</u></a> </p><ul>
  <li>介紹各種線上資料庫作為學生未來下載的各種可能性與方法。</li>
</ul><p>第六週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week6-Enzensberger_Weizenbaum" target="_blank" ><u>電腦文學基礎 Hans Enzensberger 與 Joseph Weizenbaum｜字典、條件判斷</u></a> </p><ul>
  <li>因上週 Hans Enzensberger 過世，教授決定以當週課程來緬懷與回溯其對於德國電腦科學的貢獻。</li>
</ul><p>第七週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week7-MarkovChain" target="_blank" ><u>馬可夫鏈 ｜函式、N-order text generation</u></a> </p>
<p>第八週：<a href="https://github.com/experimental-informatics/plunging-into-code/tree/master/Week8-Graph-Image" target="_blank" ><u>電腦圖像基礎 ｜多維陣列、PIL </u></a> </p>
<p>第九週：樹莓派與網路基礎｜Command Line (CMD)、python GPIO</p>
<p>--------------聖誕節後沒有人想上課跟教課於是很待定--------------</p>
<p>第十週：電腦文學與NLTK（待定）</p>
<p>第十一週：自動化 Prompt Design 與 openai API（待定）</p>
<p>密集課程：對抗式攻擊與其藝術實踐</p>


<p>資料整理：</p>
<p><a href="https://github.com/experimental-informatics/plunging-into-code/blob/master/Week3-PythonEinf%C3%BChrung02/KI-K%C3%BCnstlerinnen_Liste.md" target="_blank" ><u>【藝術家與作品列表】</u></a> </p>
<p><a href="https://github.com/experimental-informatics/plunging-into-code/blob/master/Week5-DatasetEinf%C3%BChrung/datasets-4-NLG-tasks.md" target="_blank" ><u>【List of Propaganda, Misinformation & Hate Speech Datasets】</u></a></p>
<p><a href="https://ground-zero.khm.de/portfolio/war-on-error/" target="_blank" ><u>【War on Error】</u></a> </p>
<p><a href="https://github.com/experimental-informatics/Workshop-Fernuni-Hagen/blob/master/1_Bibliothek_von_Babel.ipynb" target="_blank" ><u>【Library of Babel 巴別圖書館】</u></a></p>
<p><a href="https://gregorweichbrodt.de/project/on-the-road.html" target="_blank" ><u>【On the Road】 Based on the novel “On the Road” by Jack Kerouac and Google Maps Direction Service.</u></a> </p>

<p>論文：</p>
<p><a href="https://dl.acm.org/doi/10.1145/365153.365168" target="_blank" ><u>Joseph Weizenbaum. 1966. ELIZA—a computer program for the study of natural language communication between man and machine</u></a> </p>

<p><a href="https://dl.acm.org/doi/10.1145/3442188.3445922" target="_blank" ><em><u>Emily M. Bender, Timnit Gebru, Angelina McMillan-Major, and Shmargaret Shmitchell. 2021. On the Dangers of Stochastic Parrots: Can Language Models Be Too Big? .</u></em></a> </p>

<p><a href="https://dl.acm.org/doi/fullHtml/10.1145/3465416.3483305" target="_blank" ><em><u>Harini Suresh and John Guttag. 2021. A Framework for Understanding Sources of Harm throughout the Machine Learning Life Cycle.</u></em></a></p>

<p><a href="https://journal.culanth.org/index.php/ca/article/view/ca33.3.04" target="_blank" ><em><u>Nick Seaver. 2018. What Should an Anthropology of Algorithms Do?</u></em></a></p>

<p><a href="https://arxiv.org/abs/2005.14165" target="_blank" ><u><em>OpenAI. 2020. Language Models are Few-Shot Learners</em></u></a></p>

<p><a href="https://0x0a.li/de/algorithmische-einfuehlung-nick-montforts-megawatt/" target="_blank" ><u>Algorithmische Einfühlung: Über Nick Montforts »Megawatt«</u></a></p>

<p>"Explaining consciousness: the hard problem" Edited by Jonathan Shear</p>


<p>學習資源：</p>
<p><a href="https://web.stanford.edu/~jurafsky/slp3/" target="_blank" ><u>Speech and Language Processing (3rd ed. draft)</u></a></p>
<p><a href="https://d2l.ai/index.html" target="_blank" ><u>Dive into Deep Learning</u></a></p>
]]></content:encoded></item><item><title><![CDATA[海灘作為想像的彼方—仙納度旅行社計畫]]></title><description><![CDATA[現代之前海灘旅遊在西方脈絡中是無法被想像的。1994 年法國歷史學家 Alain Corbin 在著作《The Lure of the Sea》中爬梳現代性致使西方世界對於海洋理解的轉向。伊甸園中不存在一望無際的汪洋，無論是珀耳修斯越過汪洋斬首了梅杜莎，或是諾亞帶領群眾躲過...]]></description><link>https://www.liutingchun.com/post/xanadu-travel-agency</link><guid isPermaLink="false">62e4ba31b52c5fcdf03ce086</guid><category><![CDATA[works]]></category><pubDate>Sat, 30 Jul 2022 05:15:17 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_6da08cb86bd64e8bb9b75a4a0ff7e1d8~mv2.jpeg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<figure><img src="https://static.wixstatic.com/media/4eb1dd_6da08cb86bd64e8bb9b75a4a0ff7e1d8~mv2.jpeg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>
現代之前海灘旅遊在西方脈絡中是無法被想像的。1994 年法國歷史學家 Alain Corbin 在著作《The Lure of the Sea》中爬梳現代性致使西方世界對於海洋理解的轉向。伊甸園中不存在一望無際的汪洋，無論是珀耳修斯越過汪洋斬首了梅杜莎，或是諾亞帶領群眾躲過大洪水。中世紀之前西方文學對於海的描繪往往連接著未知、洪水、風暴、妖怪等災厄。直至啟蒙運動科學傳遞與除魅，海洋的未知幻象才在十七世紀逐漸被詩人、藝術家與文學家釐清。貴族與市民開始在海濱建立海水浴場，海灘也逐漸成為被眾人所嚮往，也成為現代旅遊的象徵。
</p>
<p>這學期做了大量海邊圖像的明信片（跪謝育葦大大幫我排版），配上十分俗氣的文字，作為創作計畫的第一階段。透過 Flickr API 大量下載了關於海灘的照片並進行圖像辨識，將得到的關鍵字排列組合之後作為Prompt 在 GPT-3 生成明信片文字的敘述與圖像的描述，再將此描述餵給 Dall-E 生成圖片。便產生了一張張如同隨處海攤皆會販售的俗濫明信片。在幾週前期末展了這些明信片之後，想把一些跟朋友討論的想法彙整一下，想以此短短的文作開端，慢慢開始對這個計畫的研究與產出。</p>

<figure><img src="https://static.wixstatic.com/media/4eb1dd_5dda6a5e6eb24ed8b11ab61b804c1d92~mv2.png/v1/fit/w_874,h_608,al_c,q_80/file.png"  ></figure>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_60a331df051446c7a024f3cbfc066723~mv2.png/v1/fit/w_874,h_608,al_c,q_80/file.png"  ></figure><p><strong>真實與數位圖像的雙重虛構</strong></p>

<p>德國在夏天為了疫情後的經濟復甦推出了九歐票政策，只要九歐元德國全境的區間快捷（RE）都可以搭乘，從六月至今每逢假日各地的車站與火車都是比肩繼踵。於此同時德國基督教民主聯盟（CDU）的主席 Friedrich Merz 則搭著私人飛機參加現任財政部長 Christian Lindner 的婚禮。婚禮舉辦在德國北部的敘爾特島（Sylt），一個德國高級的度假勝地。這座島嶼的海灘因其地理位置與氣候變遷每年都有大面積沙灘被海水侵蝕，德國政府投資了五百萬歐元運輸沙土來填海維持其地理景觀與居民的安全。</p>

<p>現代海灘多是人造的產物，旅行社、旅館、飯店兢兢業業的維持的海灘的形象。將原生的樹木搬遷以種植棕梠樹，替換海灘刺腳的砂石填入相對細小的沙粒，捕撈與消滅鯊水母等對人有害的海洋生物以保證遊客的安全，最後仔細地在夕陽餘暉下拍攝一張張海灘的形象照。波光粼粼的海面上映照著紫紅色的夕陽，棕梠樹在白淨的沙灘上搖曳，等待著遠從地球另一端飛來的旅客享受假期。這樣被製造與修圖後的畫面在世界各地的海灘屢見不鮮且大同小異。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_e74798f17cdf458cb6bb6b61299e89e1~mv2.png/v1/fit/w_800,h_800,al_c,q_80/file.png"  ></figure><p>
<strong>社群媒體導致的人工智慧演算法偏見</strong></p>

<p>人類生產的文字與圖像在現代最大的受眾已不在是人類而是機器。電腦透過學習與觀看人類的知識體系從而進行生產。既然學習過程基於人類所生產的圖像，則其中畢竟存在一定的偏見。無論是社群媒體或是線上圖庫，搜尋海灘相關的圖像皆是光鮮亮麗的白淨海灘。以這樣的圖像作為訓練資料便會造成選擇偏差（Represantation Bias），讓電腦認知的海灘圖像皆是這樣的人造景觀。與此同時當這些圖像被機器消化後試圖生成時，以此基準判斷圖片是否符合「海灘」的印象也造成了評估偏差（Evaluation Bias）。多種的偏見也造成透過 Transformer Model 生成海灘圖像時，往往會產生俗濫的海邊影像。</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_55a08ea41c184114a6d76738edd3921f~mv2.png/v1/fit/w_800,h_800,al_c,q_80/file.png"  ></figure><p>
</p>
<p><strong>仙納度—無法抵達的彼方？
</strong></p>
<p>社群媒體上的旅遊圖像，往往是拍攝者擷取的片面的真實，而接收到的閱聽人也以此偏差想像旅遊的樣貌，如同不拍攝到地面的巴黎往往是美麗的一樣。不管是拍攝者還是觀看者，這些對海灘的嚮往，都是一種不盡真實的想像，如同馬可波羅所描繪亦真亦假的元朝首都仙納度一樣。而機器學習模型在吸收與消化這些想像後所形成的模型，便是乘載人群想像的集體意識，將這些幻想以數字的方式進行拼揍，從何生產出所謂「理想的彼方」。人工智慧生產的圖像就如同上傳社群媒體的美好景點形象一般，都是永遠無法企及的。
</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_b292b3902f4d416b87e1d6beee256378~mv2.png/v1/fit/w_800,h_800,al_c,q_80/file.png"  ></figure><p>
</p>
<p><strong>後記：</strong></p>
<p>這計劃其實是兩年前申請碩士時寫的，當時提的計畫還是用 GAN 生成，但這兩年 Transformer 的濫觴，和 Dall-E 成為主流圖像生成的工具，就也從善如流了。記得兩年前坐在杜賽道夫的咖啡廳在問黃偉對計劃的意見（實際講了什麼其實也忘光了）。當初重視的內容是想談在人工智慧模型中進行「攝影」這樣的概念，然後將人工智慧模型本身作為人群集體意識的延伸，但也僅此而已。始終沒有回答究竟為何是海？前陣子晨宣傳了Jonas Bendiksen 的 The Book of Veles 給我。讓我開始想慢慢往虛構的旅遊、想像的畫面的方向發展，就開始慢慢讀現代旅遊的資料，也算是作為概念的基底。期間也發現滿多有趣的事：十八世紀末期有醫生指出海水能夠治療陽痿，於是當時相信科學的人便會到海邊去泡海水浴XD。</p>

<p>明信片在 Rundgang 展完之後，同學和朋友會很常傳給我一些很有趣的路觀，像是巨型氣球棕梠樹，或是林彥翔在捷運站拍的旅行社廣告。雖然旅遊作為主題非常的軟性，但人造海灘仍然非常具有政治性，Vorawan Kanlayanasukho 和 Patrice Veuthey 寫的 Blood on the Beach 就是很好的例子。介在這種很模糊的角度來批判好像也是個滿合乎自己希望的樣子。當初也是想保留一個批判西方對於海島國家作為「旅遊景點」的空間，才取名叫仙納度旅行社的。可能花個半年好好把這個計畫打磨一下，想想疫情那段時間對旅遊的嚮往，或許在沉澱之後會以不一樣的方式產出吧</p>
<p>
</p>
<p>喔然後，死亡擱淺真的是一款很讚的遊戲</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_34ab4456bc884db4affa66702513c351~mv2.jpeg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure>]]></content:encoded></item><item><title><![CDATA[Raspberry Pi Python燈條控制 (ws281x系列) ]]></title><description><![CDATA[這篇貼文想簡單分享一些如何使用python操作彩色LED燈條，如何安裝相關套件跟一些使用規格。原理其實跟使用Arduino搭配NeoPixel或FastLED這兩款套件相同，只是在這邊語法上會使用Raspberry Pi的GPIO與Python。如果對寫程式比較棘手，也推薦...]]></description><link>https://www.liutingchun.com/post/raspberry-pi-python-light-strip</link><guid isPermaLink="false">604b7ee561d72900577d60ab</guid><category><![CDATA[technique]]></category><pubDate>Fri, 12 Mar 2021 17:41:12 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_2c024145eb3340659134cb0f6d09dbda~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p>這篇貼文想簡單分享一些如何使用python操作彩色LED燈條，如何安裝相關套件跟一些使用規格。原理其實跟使用Arduino搭配NeoPixel或FastLED這兩款套件相同，只是在這邊語法上會使用Raspberry Pi的GPIO與Python。如果對寫程式比較棘手，也推薦直接購買LED燈條控制器 (如 T500K) 搭配適當的軟體 (LEDEdit)，就可以直接將影片map成燈光。因為發現自己始終沒有整理好的檔案，所以決定順手寫一下部落格來做個資料的整理。</p>

<p>使用python的好處是，當進行與其他軟體的互動或通訊時，相容性會高很多。遠端操作上也可以直接使用<a href="https://www.liutingchun.com/post/raspberrypi-python-osc" target="_blank" rel="noopener"><u>OSC進行通訊</u></a>，或是Websocket等等各種協定。對於只會撰寫python的朋友也會容易許多。</p>

<p>市面上大部分的單顆可控制燈條，主要的型號分為SK系列與WS281x系列。值得注意的是WS系列雖然並不是指燈本身，而且其控制晶片的名稱。LED燈泡本身還是使用5050規格。購買LED時也可以注意購買燈泡的密度，大致上分為幾種規格，<strong>每一公尺內含30, 60, 144顆燈泡</strong>，也有的燈條控制單元是以<strong>三顆燈泡為一個單位控制</strong>，並不是每顆燈泡都可以獨立操作。</p>

<p>這邊也稍微整理一下幾種常見型號，給大家看看各個型號的差異，在需要購買時以供參考。</p>
<p>細節的規格上還是有很多差異，如果有需求也可以直接去查規格書</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_ed5d093e03034228a59a3677701cc3a9~mv2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>大致的規格解說完，我們就可以開工寫python了。</p>
<p>我們這邊使用NeoPixel的library在這邊使用的語言是python3，舊版python2的library已經下架，為大家方便在這都以python3為主。</p>

<p>新版Raspberry Pi OS 預設的python依舊是2.7，如果在寫執行時覺得麻煩，可以用一行指令來將python指令轉換為直接使用python3。</p><pre><code><em>sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10</em></code></pre>
<p>首先打開terminal，輸入以下兩行指令來安裝對應的library</p><pre><code><em>pip3 install rpi_ws281x adafruit-circuitpython-neopixel
python3 -m pip install --force-reinstall adafruit-blinka</em></code></pre><p>注意是如果已經執行剛剛的指令就可以<strong>直接使用pip代替pip3，python代替python3</strong></p>

<p><strong>*****注意*****</strong></p>

<p>更新後的adafruit library，一般來說，需要使用root來操作(sudo)</p>
<p>舉例來說檔案為 <strong>light.py</strong> 就必須要用 <strong>sudo python light.py </strong>來呼叫</p>
<p>作為訊號的pin腳，只能使用D10, D12, D18, D21</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_cd37178f863947ae97f99b116415029c~mv2.jpg/v1/fit/w_1000,h_341,al_c,q_80/file.png"  ></figure><p>而有個<strong>繞過這項規則的方法</strong>，就是直接使用SPI pin腳</p>
<p>這邊要做的事情便是更改系統設定來開啟SPI使用</p><pre><code>sudo raspi-config</code></pre><p>在<strong>Interface -> SPI -> YES </strong>開啟SPI設定 就可以利用SPI的pin腳例如 D10。</p>
<p><strong>**************</strong></p>

<p>完成之後我們便可以進入python編輯了。開啟自己習慣的編輯方法，或是直接在terminal用vim開啟檔案。Vim的使用方式在前面部落格已經提過，這邊就不再贅述。</p>
<p>當然Raspberry Pi內建的Thonny Python IDE也是個不錯的選擇。</p>


<p>首先我們需要import對應的資料庫。</p><pre><code>import board
import neopixel</code></pre><p>接著初始化pixels這個變數，來操作燈條。</p><pre><code>length = 30
pixels = neopixel.NeoPixel(board.D10, length, brightness=0.8, auto_write=False,pixel_order=neopixel.RGB)</code></pre><p>這邊可以稍微解釋一下各個argument。</p>

<p><strong>使用pin腳：board.D10 </strong>(規格是以board為原則，參照上面GPIO表)</p>
<p><strong>控制燈數：length </strong>(是使用我們剛剛預設的變數 length，來存取燈數)</p>
<p><strong>亮度：brightness=0.8 </strong>(以0~1控制總亮度，在供電不足時十分方便)</p>
<p><strong>自動上傳：auto_write=False</strong> (這部分等等會再說明，與運算效率有很大關係)</p>
<p><strong>色彩編碼：pixel_order=neopixel.RGB </strong>(預設並不是習慣的RGB，建議更改一下)</p>

<p>接著我們先試著點亮他，fill會讓整條燈條都填滿紅色</p><pre><code>pixels.fill(255,0,0)
pixels.show()</code></pre><p>這邊會發現 pixels.show() 這個函式，可以講回前面提到<strong>auto_write</strong>這件事</p>
<p>當我們把auto_write設成true，每一次更動燈條顏色，他便會直接輸出這個訊號給燈條。</p>
<p>在工作上確實會方便，但當我們要個別操作每一顆個別燈條時，運算效能便會很差。</p>
<p>設定成false時，我們設定完每一顆個別的燈，之後一次輸出，會節省很多效能浪費。</p>

<p>剛剛我們學會 pixels.fill()</p>
<p>至於單顆燈的操作也很簡單，直接指定pixels陣列的index</p><pre><code>pixels[29] = (255,0,0)</code></pre><p>這樣第30顆 (陣列從0開始) 燈，便會亮出紅色。</p>

<p>接下來我們來試做流水燈效果吧，這份範本很簡單，也會有很多不同的細節可以做修改。</p><pre><code>from numpy import interp
import time

counter = 0

#初始化燈條陣列回黑色
for i in range(length):
    pixels[i] = (0,0,0)

while True:
    counter += 1
    counter %= length
    light_range = int(length/3)
    
    #先預設所有燈為黑色
    for i in range(length):
        pixels[i]=(0,0,0)
    
    #跑三分之一長的燈 設定顏色
    for i in range(light_range):
        c = int(interp(i,[0,light_range],[0,255]))
        if(counter-i)<0:
            break
        pixels[counter-i] = (c,c,c)

    pixels.show()
    time.sleep(0.005)</code></pre><p>稍微說明一下幾個函式</p>
<p><strong>interp()</strong> 是在numpy裡頭的function，用法與processing或arduino的map類似</p>
<p>我們在這邊把 i的範圍，拓展成0~255，符合RGB的設定</p>
<p>另外最後的<strong> time.sleep(0.005) </strong>則是設定每次while重複的頻率。</p>

<p>當我們可以操作單顆燈時，變化便可以自己設定。</p>
<p>祝大家玩得愉快</p>



]]></content:encoded></item><item><title><![CDATA[Raspberry Pi3 B+ 同步播放器]]></title><description><![CDATA[積欠已久，接了小工作決定邊弄邊把步驟寫出來。 同步播放器的工作方式，需要至少兩台電腦(在這邊使用Pi)在同個網域下運作。第一台作為Master，其他作為Slave。當Master在播放影片時，會在一定時間間隔不斷傳送目前播放的時間點給所有Slaves。但大家也知道，這樣的傳...]]></description><link>https://www.liutingchun.com/post/raspberry-pi3-b-plus-video-sync</link><guid isPermaLink="false">5e3548d91ae1560017e1b3ed</guid><category><![CDATA[technique]]></category><pubDate>Sat, 01 Feb 2020 11:33:59 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_4809894287bd45c9b3430a46d97b2f2b~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p>積欠已久，接了小工作決定邊弄邊把步驟寫出來。</p>

<p>同步播放器的工作方式，需要至少兩台電腦(在這邊使用Pi)在同個網域下運作。第一台作為Master，其他作為Slave。當Master在播放影片時，會在一定時間間隔不斷傳送目前播放的時間點給所有Slaves。但大家也知道，這樣的傳輸方法，會因為不同網路環境存在一定的延遲。因此，在Slaves收到訊息時，會自動Seek到對應的時間點，在把目前自己播放的時間點傳送回去給Master。</p>

<p>大致上來說，如同大家在國高中作過的「蝙蝠回聲距離問題」，當Master收到Slave回傳的訊號時，便會確認自己目前的時間點，再和自己當初傳送出訊號的時間點相減除以二。一來一往之間，Master變可以得知連結關係中的網路延遲時差，進而把目前播放時間再加上預期傳輸時間差送給所有Slaves，達成同步。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_1b03ac6f774e41ceb06bad9ea87991af~mv2.jpg/v1/fit/w_1000,h_720,al_c,q_80/file.png"  ></figure><p>本篇將解釋如何目前最流通的Raspberry Pi3 Model B+ 製作同步播放器。主要使用的軟體是這份：<a href="https://github.com/turingmachine/omxplayer-sync" target="_top" rel="noopener">https://github.com/turingmachine/omxplayer-sync</a></p>
<p>之所以特別標註B+的原因，一來是自己習慣使用B+工作，二來是B+在使用這套軟體時，會遇到非常多問題導致無法正常安裝乃至於作業系統整個弄壞。在這邊附上另外找到的解決方法。</p>


<h2><strong><em>基礎設定</em></strong></h2>
<p>關於Pi如何登入連結等等，就詳見一篇部落格</p>
<p><a href="https://www.liutingchun.com/post/raspberry-pi-basic" target="_top" rel="noopener">https://www.liutingchun.com/post/raspberry-pi-basic</a></p>

<p>當我們得到一台安裝好的Pi之後（我使用的作業系統是2018-11-13-raspbian-stretch）便可以開始進行基礎的設定。首先要在Preferences的Raspberrypi Pi Configuration中，進行三個步驟，過程中會詢問是否要重新開機，都先略過，等所有設定都完成再一次重啟。</p><ol>
  <li><strong>調整記憶體用量至512</strong>：方便播放影片不會卡頓</li>
  <li><strong>開啟所有預設通道設定</strong>：使我們可以使用VNC或SSH工作</li>
  <li><strong>調整畫面解析度</strong></li>
</ol><p>進行完成之後就可以重新開機等待完成</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_930e7beee924484487baa59fb33e55ff~mv2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_f98ab4ce781a4129931a06bb2017fb9d~mv2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><h2><em><strong>安裝軟體</strong></em></h2>
<p>再登入之後我們便可以開始基礎設定。</p>
<p>開啟我們的Terminal之後，我們要先進行函式庫的更新以及安裝，以及修改我們的Boot檔案</p><pre><code><em><strong>sudo apt-get update
sudo apt-get install vim</strong></em></code></pre><p>Vim安裝完成之後便可以開始撰寫以及修改我們的Code。</p>
<p>第一件要做的事，是把音效雜訊移除，以及關閉hdmi畫面中的閃電符號</p>
<p>在terminal中我們要先修改/boot/config.txt 檔案</p>
<pre><code><strong><em>sudo vim /boot/config.txt</em></strong></code></pre>
<p>之後我們會以vim開啟config.txt檔案，此時把游標一路推到檔案最下面</p>
<p>先輸入 i 或 a 開始編輯，在最下方輸入</p><blockquote>audio_pwm_mode=2
avoid_warnings=1 </blockquote><p>之後鍵盤按下 <strong>esc</strong> 離開編輯模式 再輸入 <strong>:wq</strong> 變可以存檔跳出。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_f887142c7e9b49c89fac52f51b7315d0~mv2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>這時我們便可以開始安裝omxplayer-sync。</p>
<p><a href="https://github.com/turingmachine/omxplayer-sync" target="_top" rel="noopener">https://github.com/turingmachine/omxplayer-sync</a></p>
<p><u>記住，千萬別使用Readme中推薦的安裝方法。請直接接著閱讀。</u></p>

<p>omxplayer在前幾篇文章中介紹中，是使用raspberry pi時的其中一個播放器軟體。</p>
<p>我們需要經過如下步驟進行安裝，首先打開Terminal</p>
<p>我們要先登入超級使用者 (super user)接著進行函式庫升級以及安裝。<u>每一條都會需要一點時間，特別是upgrade會耗時非常非常的久。在這邊就需要耐心等待。中間要記得按下各種q或Y。</u><strong>每一步驟請盡量按照步驟執行，跳過任何一步，很容易出問題。</strong></p>
<blockquote><pre><em>sudo su
apt-get update
apt-get upgrade
apt-get install libghc-these-prof
apt-get install libghc-terminal-size-prof
apt-get install libglib2.0-dev
apt-get install libgtk2.0-dev
apt-get install --reinstall python-gi
apt-get install ffmpeg</em></pre></blockquote><p><pre>接著我們要移除原有的omxplayer 以及重新安裝新的軟體</pre></p><blockquote><pre><em>apt-get remove omxplayer
rm -rf /usr/bin/omxplayer /usr/bin/omxplayer.bin </em></pre>
<pre><em>rm -rf /usr/lib/omxplayer</em></pre>
<pre><em>apt-get install libpcre3 fonts-freefont-ttf fbset </em></pre>
<pre><em>apt-get install libssh-4 python3-dbus</em></pre></blockquote>
<p>排版關係他被切開了，但請記得把以下的指令都要<u>用一行打完喔</u></p><blockquote><pre><em>wget https://github.com/magdesign/PocketVJ-CP-v3/raw/master/sync/omxplayer_0.3.7-git20170130-62fb580_armhf.deb</em></pre>

<pre><em>dpkg -i omxplayer-0.3.7-git20170130~62fb580_armhf.deb</em></pre></blockquote>
<blockquote><pre>wget -O /usr/bin/omxplayer-sync <u>https://github.com/turingmachine/omxplayer-sync/raw/master/omxplayer-sync</u></pre></blockquote>
<p><pre>最後我們需要在系統授權omxplayer的使用</pre></p><blockquote><pre>chmod 0755 /usr/bin/omxplayer-sync
chmod 0755 /usr/bin/omxplayer</pre></blockquote><p><pre>以及修正一些前段時間安裝的錯誤</pre></p><blockquote><pre>apt --fix-broken install
apt-get install libpcre3
apt --fix-broken install</pre></blockquote>
<h2><strong><em>軟體測試</em></strong></h2>
<p>首先我們先打出</p><pre><code><strong><em>exit</em></strong></code></pre><p>退出super user模式。</p>
<p>接著為了方便工作，我們可以在桌布上建議一個新的資料夾，然後下<pre>載測試影片開始測試。</pre></p><blockquote><pre>mkdir /home/pi/Desktop/autoplay</pre>
<pre>cd /home/pi/Desktop/autoplay</pre></blockquote><p><pre>以下也是一行打完</pre></p><blockquote><pre>wget https://github.com/turingmachine/omxplayer-sync/raw/master/synctest.mp4</pre></blockquote><figure><img src="https://static.wixstatic.com/media/4eb1dd_259a63d93f4e4a8d90cd64db3a46f227~mv2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>接著我們打上 </p><pre><code><strong><em>omxplayer-sync -muv synctest.mp4</em></strong></code></pre><p>變可以測試影片是否正常播放，請記得如果是在VNC模式下，是不會有畫面的。如果需要退出，按下Ctrl-C即可。</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_4809894287bd45c9b3430a46d97b2f2b~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><h2><strong><em>實際使用</em></strong></h2>
<p>我們可以在另一篇文章中找到開機自動執行的方法，請記得在sh檔案中，在master裡加上15秒延遲，slaves中加上20秒。可以確保開機之後pi已經正確完成所有初始化，以及連上網路。</p>
<p><a href="https://www.liutingchun.com/post/raspberry-pi-basic" target="_top" rel="noopener">https://www.liutingchun.com/post/raspberry-pi-basic</a></p>
<p>請記得所有檔案名稱都需要相同。</p>

<p>Master執行的指令為</p><pre><code><strong><em>omxplayer-sync -mu -a fill -o both [檔案名稱]</em></strong></code></pre><p><em>Slave則是</em></p><pre><code><em><strong>omxplayer-sync -lu -a fill [檔案名稱]</strong></em></code></pre><p>在這邊打一些註解</p>
<p>-v 顯示詳細資料，會在影片播放時顯示時間</p>
<p>-u 循環播放</p>
<p>-m 設置為master</p>
<p>-l 設置為slave</p>
<p>-o both音效設置 <pre>both為同時在3.5mm和hdmi播放</pre></p>
<p>-a fill 全螢幕播放 (也有其他模式<pre>fill, letterbox, stretch)</pre></p>
<h2><strong><em>備註</em></strong></h2>
<p>在軟體官方頁面有幾點注意事項，在這邊小小翻譯一下，再附上一些我自己的註解。</p><ul>
  <li>請記得將所有pi都<strong>連到同個子網域</strong>，建議用有線接hub效果可能更好。</li>
  <li>第一次輪播影片，會同步不了是正常的。</li>
  <li>播放在不同pi的檔案，<strong>檔案名稱必須要相同</strong>。</li>
  <li>在播放檔案的資料夾，<strong>請不要放入其他無關檔案，否則同步容易失敗。</strong></li>
  <li><strong>網路需要先連結</strong>，再開啟同步軟體，否則Master不會傳送資料</li>
  <li>Slave檔案中，請勿使用audio的參數</li>
  <li><strong>請使用h264檔案，並且影片長於60秒</strong></li>
</ul>

<p>最後附張之前在府中和阿芝芳境王量弄展覽同步播放的工作圖</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_80c7db8b444b4d0e8ed9807f3ea952a4~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure>
]]></content:encoded></item><item><title><![CDATA[Processing 蒙地卡羅演算法做文字動畫]]></title><description><![CDATA[標題很聳動，但其實也就是用了蒙地卡羅方法來計算文字在空間中的佔比。寫一點技術文章，這篇要先感謝家豪冠廷家陞可以一起快樂寫程式，還有淳俐剛好在柏林表演找我湊一腳很隨便的live-coding視覺，才有辦法把這東西弄完。這份Code有點類似高中在玩BBS的時候有些windows...]]></description><link>https://www.liutingchun.com/post/processing-text-animation</link><guid isPermaLink="false">5dc477db4704be0017000f0c</guid><category><![CDATA[technique]]></category><pubDate>Thu, 07 Nov 2019 20:51:32 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_11e226901ce04a8e94da95c93cef0145~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p>標題很聳動，但其實也就是用了蒙地卡羅方法來計算文字在空間中的佔比。寫一點技術文章，這篇要先感謝家豪冠廷家陞可以一起快樂寫程式，還有淳俐剛好在柏林表演找我湊一腳很隨便的live-coding視覺，才有辦法把這東西弄完。這份Code有點類似高中在玩BBS的時候有些windows的軟體可以做Ascii art，把圖片或影片轉換成文字效果，一直在想有什麼演算法可以去實踐它……，後來用蒙地卡羅演算法(Monte Carlo algorithm)硬幹出來惹。恥恥的，其實到現在還沒辦法真的理解使用上，蒙地卡羅演算法跟蒙地卡羅方法的差別，跪求解釋。這篇會分兩段去寫分別會是如何使文字流動起來，和如果轉換圖像文字。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_21d53832d0a9486288a5352b0453b894~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" title="首圖先自肥" ></figure><p>更新一下近況，好不容易在杜塞道夫註冊完居住地，終於算是半個杜賽人了。有時間其實寫一些畢業之後小心得寫了一半，但有點太恥不敢發，再修一下過幾天再說。</p>

<p>之前寫不少Python的部落格，想來寫寫最近用Processing玩的小玩意。起因是那天在河堤邊被林彥翔嘴正在實驗的新作品視覺太醜，翻來覆去睡不著，隔天就想來玩玩看用文字來模擬流動的效果。然後有沒有辦法把這樣的動態map到影像上。後來剛到德國時淳俐在柏林有表演找了我去做視覺湊一腳，就用了這個效果來玩。</p>

<p>在玩Ascii art時，當時都是一格一格描圖在那邊對色號畫出來的，或是抽選不同的文字慢慢試出來，也有些軟體或網頁可以做到輸入圖片，置換出文字檔，但既然可以自己做當然要自己玩囉。最開始寫這份Code的時候，因為喝酒所以寫的很亂，所以code的部分就不贅述太多，單純講一些實行方式，頂多用一兩行來註解一下比較關鍵的部分。</p>
<p>在這邊附上一些ascii art的連結：<a href="https://lmgtfy.com/?q=ascii+art&#38;s=g" target="_top" rel="noopener">https://lmgtfy.com/?q=ascii+art&s=g</a></p>
<h2>第一部分：文字流動</h2>
<p>最一開始的時候是先從想讓文字流動開始，首先先寫一個可以佈滿畫布(Canvas)存放char的二維陣列(這邊先命名為text)，因為我很懶得算，所以陣列大小就是[width+1][height+1]每一個二維陣列先存取一個隨機的文字，然後平鋪在畫布上。然後按著畫面位置上點色。</p>

<p>另一個部分是記得做textAlign(CENTER);，讓文字對齊在指定的位置中間(雖然字體的關係會有點下偏)。</p>
<blockquote>for (int x=0; x<=width; x+=10) {
      for (int y=0; y<=height; y+=10) {
            text[x][y] = char(int('a'+random(26)));
      }
} 
for (int x=0; x<=width; x+=10) {
      for (int y=0; y<=height; y+=10) {
            fill(255,100); //上色
            text(text[x][y], x, y);
      }
}</blockquote><figure><img src="https://static.wixstatic.com/media/4eb1dd_91f6b3481a5841f89077ac55e762fa94~mv2_d_2303_1632_s_2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>稍稍解釋下 Ascii 碼，附上一張精美的Ascii Table。我們可以看到小寫 a 的編號是97，之後的連續25個字母都是英文小寫，因此我們要亂數產生英文小寫的話，只需要先整數運算出 ‘a’ + random(26) 之後去強轉成整數，小撇步是加成乘除運算，系統會自己默認為數字運算。之後只要強轉回char()就得到字母了。</p>

<p>最後就形成這張圖～～</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_d6e99e5207a44a1c8cb424b8e3b2d7a9~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>下一步想要做出類似駭客任務的流動效果，只要在最上面那排不斷的隨機生成文字。然後再隨機的條件下，會讓下面的陣列位置繼承上面的文字，就會有這種效果，而調整Random的參數，也可以影響線條的長短流速等等。</p><blockquote>for (int x=0; x<=width; x+=10) {
      text[x][0] = (char('a'+int(random(25))));
}
for (int y=10; y<=height; y+=10) {
      for (int x=0; x<=width; x+=10) {
            if (random(5)>3)
                  text[x][y] = text[x][y-10];
      }
}</blockquote><p>執得一提的部分是，比較正確的程式撰寫邏輯，在換取的程式中，一般來說會習慣還是從底部一路換上去，就不會發生一次替換一整排的效果，但假設有了隨機的部分，也可以做出比較長條的線條，可以自己實驗看看下兩種方法。</p><blockquote>for (int y=height; y>=10; y-=10)
for (int y=10; y<height; y+=10)</blockquote><figure><img src="https://static.wixstatic.com/media/4eb1dd_343742a8ae624b6a843f5724d8585a65~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>重複製作由左至右的流動之後，就會有這樣大小色塊的狀態出現。</p><a href="https://video.wixstatic.com/video/4eb1dd_2f01b930b0724a738bc039138a696753/480p/mp4/file.mp4">https://video.wixstatic.com/video/4eb1dd_2f01b930b0724a738bc039138a696753/480p/mp4/file.mp4</a><p>也因此會發現，<strong>一些文字例如 i, o, c 等等，會有比較多黑色的佔比，而大的文字則可以填出比較滿得色彩。</strong>而這些佔比較小文字也形成類似河流中不同的效果。這就回到最初的疑問，要怎麼樣知道哪些文字佔比高，哪些文字佔比低，然後可以把它套用到圖片使用上。</p>


<h2>第二部分：圖像轉文字</h2>
<p>總之核心部分是高中時候用來練習算圓周率的蒙地卡羅演算法，如下圖。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_ce1288dae775462dbd9838d762318be6~mv2.jpg/v1/fit/w_458,h_465,al_c,q_80/file.png"  ></figure><p>數學沒很好但大致解釋一下最簡單的使用方法就是計算圓周率的近似值。我們可以知道半徑為r的四分之一圓的面積為π*r*r/4，而邊長為r的正方形面積為r*r。兩者比值為π:4。因此我們可以在xy軸最大為r的情況下，隨機取樣，只要其距離與(0,0)小於r，便可以視為在圓內，再把圓內的所有點的數量加總起來。假設我們隨機打了10萬個點其中可能有X個點在圓內，則可以得知 100000:X = π:4 ，套入國中學會的方法(是國中吧？)便可以得知π = 400000/X。這樣的方法可以得知圓周率的近似值，而想當然爾，取樣的數字越高10萬100萬1000萬，數值就會越精準。</p>

<p>好了，廢話太多，跳回原本在計算文字的部分。我用了同樣的方法來計算文字在框格中的佔比，不同的Font自然大小也不同，比例也不同，這邊先以Processing-Java內建的SansSerif做說明。</p>

<p>首先因為我們只要取的是相對的比例，因此只要套用同一種尺寸作為標準即可(這部分我做的非常懶散)，我們先將所有要計算的符號套入一個一維陣列，包含26+26大小寫英文字幕以及14個符號。懶得加總的人，當然也可以在setup當初寫一個 int index_length = index.length; 來計算總數。然後也在全域變數的地方宣告一個用來記錄的陣列。</p><blockquote>char[] index = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '+', ' ‘};

float[] index_density;</blockquote><p>我們將內建的文字固定好位置開一個800x800的canvas之後，把字型大小設定成500pt。並初始化儲存用的陣列。</p><blockquote>size(800,800);
textAlign(CENTER,CENTER);
textSize(500);
index_density=new float[index_length];</blockquote><p>設置成500的原因，是因為qp等等字幕有些會往下超出框格範圍，因為我們只要相對比例，因此我們將所有文字大小都縮小。</p>

<p>然後回到原先使用蒙地卡羅的方法，一個一個畫上新的文字，打上十萬個點，計算比值。Processing快樂的地方就出現了，計算新增取樣的點是否在文字上的方法，只要用get()去抓顏色，將底色設定為白色，文字設定成黑色，當get到的數字是黑色時，便可以知道是否取樣到的點在文字上。下圖先順帶上色示意，但實際在執行的時候，要記得畫面上切記不能有其他數字顯示，或是畫上新東西，會導致取樣失準喔。</p>

<p>100萬個點的示意圖。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_7548e3e42137477a894c3020946c6f8a~mv2.jpg/v1/fit/w_800,h_800,al_c,q_80/file.png"  ></figure><p>取出來的數字最後去做百分比和去小數點的動作。先把要除的數字都先轉為小數，才不會出錯，然後用nfc去小數點後三位。</p><blockquote>nfc((float(total)/float(1000000))*100, 3));</blockquote><p>再把每一個文字都做過一次，就得到一串陣列了。</p><blockquote>float[] index_density = {4.595, 5.98, 3.475, 5.964, 4.46, 3.819, 6.538, 5.446, 2.25, 3.421, 5.131, 2.788, 7.01, 4.547, 4.703, 5.808, 5.809, 2.502, 3.456, 3.181,4.626, 3.487, 6.27, 3.945, 4.296, 4.2, 6.145, 7.078, 5.328, 7.283, 5.367, 4.456, 6.068, 6.606, 2.782, 3.793, 5.865, 3.744, 9.116, 7.354, 7.154, 5.516,8.077, 6.755, 4.99, 4.363, 5.898, 4.961, 9.212, 5.624, 4.408, 5.674, 1.737,2.119, 7.047, 5.383, 5.19, 6.321, 2.727, 7.452, 1.506, 2.689, 2.71, 1.173, 2.911, 0.0};</blockquote><p>之後只要再對其作比值排序，這邊我很懶，我就直接寫個很簡單的Bubble Sort，在做數字交換時，同時交換文字，最後得到的文字陣列，便是我所需要的排序好的文字佔比。每次實作都會有誤差，可以大家換字體或是增加取樣數自己試試看。</p><blockquote>for (int i=0; i<index_length-1; i++) {
      for (int j=i+1; j<index_length; j++) {
            if (index_density[i]>index_density[j]) {
                  float tempF = index_density[i];
                  index_density[i] = index_density[j];
                  index_density[j] = tempF;
                  
                  char tempC = index[i];      
                  index[i] = index[j];
                  index[j] = tempC;
            }
      }
}</blockquote><p>最後就取得我們要的漂亮答案。算完之後便可以把這串文字整理起來直接應用。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_d7ba4e86f4244a4d8c0d7e6d4e62252c~mv2.jpg/v1/fit/w_800,h_800,al_c,q_80/file.png"  ></figure><p>這串文字應用方法很多，我們可以直接map到顏色，上不同彩度，或是分區間製造一點隨機性。</p><blockquote>PImage img = loadImage("XXX.jpg");
for (int x=0; x<width; x+=10) {
      for (int y=0; y<height; y+=10) {
            //map對應的畫布位置
            int gx = floor(map(x, 0, width, 0, img.width)); 
            int gy = floor(map(y, 0, height, 0, img.height));
            fill(255,0,0, 60);
            text(index[floor(map(brightness(img.get(gx, gy)),255, 0, 0, index_length-1))], x, y);
      }
}</blockquote><p>可以透過這樣的方式，取得原圖像對應畫布位置的色塊，再透過不管是飽和度(Saturation)，明度(Brightness)，甚至是RGB等等，map出不同的效果。選取的方式，也要試圖片而定，圖片假設所有pixel的飽和度都很高，那選擇Brightness效果就沒那麼好。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_b68be64535d54be1a51facd9aa5e18b8~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>也可以同時疊加很多層次，然後取圖片上同樣位置的red, green,blue比例，對應的放上上了顏色的文字，也會有一種特殊的效果。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_b2d99e39a5284aa9a75d56d79c0f336d~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>相當不錯的地方是，影片也跑得起來呢！</p><a href="https://video.wixstatic.com/video/4eb1dd_1aad04cfdb5543a4b427e80857c402f0/480p/mp4/file.mp4">https://video.wixstatic.com/video/4eb1dd_1aad04cfdb5543a4b427e80857c402f0/480p/mp4/file.mp4</a><p>大致上的內容差不多就這樣，附上分析的github連結。最近作業好多，過幾天再把Readme.md打完，嘖嘖</p>
<p><a href="https://github.com/aprilcoffee/FontDensityCalculation/blob/master/FontDensityCalculation.pde" target="_top" rel="noopener">https://github.com/aprilcoffee/FontDensityCalculation/blob/master/FontDensityCalculation.pde</a></p>

]]></content:encoded></item><item><title><![CDATA[Raspberry Pi 以 Python 使用 OSC 通訊協定傳送資料]]></title><description><![CDATA[這篇來寫寫如何在Python當中使用OSC通訊協定傳輸基本的數字，稍微解釋一下何為OSC還有其應用範圍，然後做一個簡單的Server/Client端的使用說明，比較複雜的用途(Broadcast、Bundle、或是如何做複雜Parsing)就先跳過, 簡單易懂為主。...]]></description><link>https://www.liutingchun.com/post/raspberrypi-python-osc</link><guid isPermaLink="false">5d6d320ff2a36e0017e1c218</guid><category><![CDATA[technique]]></category><pubDate>Mon, 02 Sep 2019 15:22:14 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_c9bf8ebe609346249c6ff339643a8f68~mv2.png/v1/fit/w_386,h_222,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p> </p>
<p>這篇來寫寫如何在Python當中使用OSC通訊協定傳輸基本的數字，稍微解釋一下何為OSC還有其應用範圍，然後做一個簡單的Server/Client端的使用說明，比較複雜的用途(Broadcast、Bundle、或是如何做複雜Parsing)就先跳過, 簡單易懂為主。</p>

<p>這篇使用的語言主要以 Python 為主，TouchDesigner, Processing, Unity 或是 MaxMsp 的 OSC 網路教學資源很多很多就自己查吧。看完這篇再搭配之前的 python GPIO 撰寫，就可以利用自己的 Raspberry Pi 和 PureData 製作自製電子樂器了～～</p>

<p>OSC全名為 Open Sound Control，是個基於 UDP 的通訊協定(也可以用 TCP 不過就不贅述)，被大量應用於聲音相關軟體，可以做區域網路內簡單資料的傳輸。不管是跨機器、或是跨軟體，都是傳輸資料簡單好用的工具。舉例來說，當我要將 Ableton Live 中某一軌聲音的音量視覺化，便可以傳送一個 OSC 封包給 Processing 或是TouchDesigner，得到這個參數之後，便可以做調整。或是在基於 Raspberry Pi 中以 Python 撰寫的 GPIO 收到感測器訊號時，也可以將參數傳送到 PureData 來生成聲音。一個OSC的封包主要分為兩種OSC Message或是OSC Bundle，這邊以比較簡單常用的Message為主解釋。</p>

<p>一個 OSC 的 Message 基本上分為三個部分</p>
<p>OSC Address Pattern ： 是一個由字符 ‘/’ 開始的 String，我們可以想像傳輸資料的名稱。</p>
<p>OSC Type Tag String ： 一些老版本的OSC會忽略它，主要說明Arguments的資料型別。</p>
<p>OSC Arguments ： 是為實際傳輸的資料內容，可以是零個也可以是多個字串或數字。</p>
<p> </p>
<p>一個基本的OSC訊號傳輸時，可以只傳送兩個部分，Address Pattern還有Arguments</p>
<p>假定我們在Max/Msp時用一個message框起來 就會長這樣</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_c9bf8ebe609346249c6ff339643a8f68~mv2.png/v1/fit/w_386,h_222,al_c,q_80/file.png"  ></figure><p>這裡是指Address Pattern為/msg 而 Arguments 也就是資料為 0 和 1 兩個</p>
<p>題外話一下，Max/Msp的 udpSend , udpReceive都不是真的udp，而是指osc。</p>

<p>在使用 OSC 時分為Client和Server兩端。我自己習慣上 Server 通常作為接收端，而Client通常作為發送端 (Boardcast時另當別論)。需要注意的是通常需要在Server端軟體開啟的情況下，Client再開啟會比較安全唷～～</p>

<p>Python 當中可以使用OSC的套件很多，我自己非常習慣使用 pyOSC 這個套件，簡單好用。但缺點是不支援太複雜的功能。如果有其他需求，也滿推薦 python-osc 的。</p>

<p>安裝方式如下</p>
<p>sudo pip install pyOSC</p>
<p>就安裝完了 ._./</p>

<p>那我們就可以開始撰寫Python了～</p>
<p>一樣我們先開始一個檔案來撰寫osc傳輸，可以選擇在Desktop或是/home/pi直接建立都可以。</p><blockquote>sudo vim oscServer.py</blockquote><p>開始撰寫之後，我們需要先匯入對應的 library。</p><blockquote>from OSC import OSCServer,OSCClient, OSCMessage</blockquote><p>這邊先以Server端我們主，Server我們的任務很間單，就是開啟電腦的通道，讓別人可以傳送資料進來。所以我們需要開放自己的ip以及對應的port。ip 可以想像成電腦的地址，而 port 則是開啟的房門通道。這個通道在電腦使用的非常頻繁，凡事需要電腦主機溝通的軟硬體，都會使用到一個port，而有些則是固定使用特殊的port來溝通，例如port 22是可以做ssh的通道，80和443則是平常我們在使用瀏覽器時連結網站資料傳輸時的port。一台電腦可以開幾萬個 port 而如上所述，因此通常建議在使用自己撰寫的程式時，都會建議大家開到 5000-60000，來防止與電腦其他軟體衝突。我們在這裡就以9527為範本。</p><blockquote>server = OSCServer((“0.0.0.0”,9527))</blockquote><p>server便是我們開始server的變數，ip對應是0.0.0.0也就是開放所有ip進入的意思(這邊說明的比較隨便，有興趣可以自己搜尋)，基本上固定事自己電腦ip即可，但懶得查的話可以用’0.0.0.0’，port則是9527，要記住這個9527，因為等回client端也需要相對的port來傳輸資料。</p>

<p>接著我們需要一個 Message Handler 來承接資料，每當有 osc 訊號傳入 server 時，Handler就會觸發我們去執行一個Function。而因為python程式碼是由上而下讀取，我們也需要先定義一個Function來讓Handler知道他要執行什麼。</p><blockquote>def msg_callback(path, tags, args, source):
       print(int(args[0]))

server.addMsgHandler( “/msg”,msg_callback)</blockquote><p>首先 python 在宣告一個function時，需要使用 def 來開頭，其後就是 function 的名字，括號內則是接收到的參數 ( parameter ) 最後是一個很容易忘記的冒號。</p>

<p>參數中，我們可以不用管 path, tags, source 有興趣的朋友可以自己print出來看看。我們需要注意的是 args，他是對應一個 OSC Arguments 的陣列。所以我們用 args[0] 來讀取陣列的第零個資料，數字可以無限增加，端看你一次增加 (Append) 多少資料。另外要注意的是 int() 這邊可加可不加，視接下來如何使用資料而定。</p>

<p>之後是addMsgHandler的部分，是告訴這份 python 程式，當我接受到什麼樣的Address Pattern時，需要執行哪一個函式 (Function) ，在這裏是指，如果我收到的osc訊號包含 /msg 時，我便會執行msg_callback這個Function。而且對應的 Function 就可以將我的資料Print出來，你也可以將它放入另一個變數，或是執行任何內容。</p>

<p>最後我們要讓我們的程式不斷地等待 OSCMessage 傳送過來，所以我們要這樣寫。</p><blockquote>while True: 
       server.handle_request()</blockquote><p>這樣就是完整的接收端(Server)程式了。</p><blockquote><em>from OSC import OSCServer,OSCClient, OSCMessage
server = OSCServer((“0.0.0.0”,9527))
def msg_callback(path, tags, args, source):
 </em>      <em>print(int(args[0]))
server.addMsgHandler( “/msg”,msg_callback)
while True: 
</em>       <em>server.handle_request()</em></blockquote><p>接著讓我們撰寫Client端，這邊就更簡單了。</p>
<p>一樣我們先include函式庫，還有設定我們要對輸的對象</p><blockquote>from OSC import OSCServer,OSCClient, OSCMessage
client = OSCClient()
client.connect(('127.0.0.1', 9527))</blockquote><p>這邊是先宣告一個變數client來當作client端接收，然後讓他連結(connect)至對應的地點，也就是ip 127.0.0.1 還有port 9527。127.0.0.1是自己電腦的地址。這樣我們就連接到我們的server了。如果今天是要連線至其他電腦或設備，記得要先找到其他電腦的ip喔。</p>
<p>（題外話，Mac查詢ip的方式，是按著option之後左鍵點一下上方wifi按鈕）</p>
<p>接著是資料的部分，如上所述，Message我們需要兩個內容，一個是 Address Pattern 一個是 Arguments。</p><blockquote>oscmsg = OSCMessage() 
oscmsg.setAddress("/msg") 
oscmsg.append(0)</blockquote><p>首先我們先宣告一個變數 oscmsg 來作為 Message ，然後設定他的 Address Pattern 為 /msg，最後我們用append的方式加入資料，每次 append 都是加入一個新的資料。舉例來說如果我寫了如下</p>
<p><em>oscmsg.append(3)</em></p>
<p><em>oscmsg.append(7)</em></p>
<p><em>oscmsg.append(‘H’)</em></p>
<p>那當我在接收時，arg[0]便是3，arg[1]會是7，最後arg[2]會是字元H。可以自己搭配使用。</p>
<p>最後我們需要將oscmsg透過client送出。</p><blockquote>client.send(oscmsg)</blockquote>

<p>完整的發送端(Client)程式如下</p><blockquote><em>from OSC import OSCServer,OSCClient, OSCMessage

client = OSCClient()
client.connect(('127.0.0.1', 9527))

oscmsg = OSCMessage() 
oscmsg.setAddress("/msg") 
oscmsg.append(0)
client.send(oscmsg)</em></blockquote><p>這樣就可以傳送了資料了，最下面的四行，也就是從宣告到傳送，可以在我們需要傳輸資料時使用，例如當我們在GPIO程式中，讀取某一個pin腳的數值，便可以將這個數值傳輸出去。</p>
<p>例如：</p>
<p><em>number = digitalRead(23);</em></p>
<p><em>oscmsg = OSCMessage() </em></p>
<p><em>oscmsg.setAddress("/msg") </em></p>
<p><em>oscmsg.append(number)</em></p>
<p><em>client.send(oscmsg)</em></p>
<p>這樣便可以將接收到的數字傳送出去～</p>
<p>基本的python中使用OSC大概就是這樣，祝大家玩得愉快。</p>]]></content:encoded></item><item><title><![CDATA[Audio-Visual 作品 Lift-Off]]></title><description><![CDATA[拖欠很久的文，最近終於空下來還個債。 2018.10.07 7:21 p.m. Space X 發射 Falcon 9 ，將 SAOCOM-1A 衛星送進地球同步軌道，在美國西岸夜空留下一道彩雲。12分鐘後，火箭脫離並完成了回收作業。...]]></description><link>https://www.liutingchun.com/post/lift-off</link><guid isPermaLink="false">5d5ea47c554ecc00160faf35</guid><category><![CDATA[works]]></category><pubDate>Thu, 22 Aug 2019 14:35:16 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_158dba8f22174d9fae12284b424d2f88~mv2_d_4096_2617_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p> </p>
<p>拖欠很久的文，最近終於空下來還個債。</p><blockquote><em>2018.10.07 7:21 p.m. Space X 發射 Falcon 9 ，將 SAOCOM-1A 衛星送進地球同步軌道，在美國西岸夜空留下一道彩雲。12分鐘後，火箭脫離並完成了回收作業。</em></blockquote><p>
<a href="https://vimeo.com/347720746" target="_top" rel="noopener">https://vimeo.com/347720746</a> (Lift-Off Vol.3 記錄於 2019.06.14  松山文創園區)</p>

<p>這件演出一共作了四次，每次都有些技術或內容上的修繕，自從B1那場之後整份Max patch就變成偽techno的形狀改都改不掉，然後學弟妹畢業展開幕的四面投影也滿挑戰自己的極限了，想想也是差不多可以整理一下半年做這件作品的心得和想法。總之能到這階段有不少人需要感謝。起手式先謝謝王老闆連晟先生的支持鼓勵，謝謝Puta大大教育和建議(含淚)，亂大的鼓勵跟意見，黃偉淳俐蔡昉阿芝芳境子馨秦威陳亮晏慈，俊輝盈文靖雅育葦彥翔提姆，還有很多很多在這件作品都有著墨或是建議的人們。言盡於此，寫太多會像畢業感言。</p>

<p>這篇文章稍微會稍微點一些畢業至今做了些什麼事情，也順便整理自己體感進步的過程，真正畢業一年的心得還是另一篇文章再把他寫完吧。然後稍微簡述一下自己作這件 Audio-Visual 演出的方法和原因，不過大多是碎嘴的故事，技術性的部分可能就稍微提一下。</p>
<p>稍微回到大學時期(即使現在講出這句話還是有夠彆扭)，那時做演出很多時候都是開心玩，每次表演不管間隔都是做些新東西，跑些所謂戲謔似稱之為「Processing Example」的效果，然後轉一轉我的mixer做噪音，稍微用個Max作輔助。而這樣的方式在日後看來，很難有實際技術上進步的空間，塑造出來的視覺或聲音也不夠深刻。大概也是這次開始認真以Max為主作聲音，接好Processing作視覺的cue點。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_a7950d7ed5f7470180552e3a25c8445e~mv2_d_5184_3456_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" title="「A/V衝刺班_噪流實習vol.1」 2018.12.08" ></figure><p>當時跪謝有了噪流這個學習跟認識朋友的機會，自己也從講師身上撈了不少東西，雖然我開 Windows 玩還願時把TouchDesigner刪掉了(X，而除了上課之外再沒打開過PureData，但其實每個講師身上都偷了一兩招來用在自己習慣的軟體上，像是亂大怎麼做演出的敘事，Puta大大怎麼處理聲音和影像的分析和想像，蝦爸如何發現自己視覺的延伸。當時在上噪流課程時，是亂大的部分，談到自己怎麼建構一套演出，從一個一個故事去出發，怎麼從起點去建構出帶有時間性的演出。而這件的開始源自於一部網路上的影片，那時只是有點嚇到一直懷疑是不是AE剪出來的，然後花了不少時間一直在看一些SpaceX或NASA的影片，另外推個網路教學平台Master Class裏頭 Chris Hadfield 開的課程也真的很好看。（附個可愛影片：<a href="https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKaOC9danxNo%26fbclid%3DIwAR2ZCy2kd91QjGomYaskhgat9ZZkBQIGEmjkqQVGgHK6ekbNcz4NuXO0m9Y&#38;h=AT2Exo73PHd_RdR_eXaWQOwTGBfr1-bciletnyf6bgle_xIgUvL4mQGNysYYYPANZitst4rSBctNw573nKCUXvzUaXl-PT_9DMBBglWp8vKKKjHm9EAHqI6Lhow2xxogcunHX_1lkxY" target="_top" rel="noopener">https://www.youtube.com/watch?v=KaOC9danxNo</a>）</p>

<p>當時自己也想說是否能以同樣的方式，以此角度為起點，生出一場表演。第一次演出機會是2018.11.12學弟妹的系展「“ ”媒體藝術學系」開幕，便以這場演出來做空總表演的測試版。當時起點有兩個，一個就是想以宇宙為主題發想出三個段落，「探索、星球、遇到外星人」XD，第二就是當時覺得寫出球體貼圖在技術上很有挑戰性，想嘗試搞死自己看看。用beginShape(TRIANGLE_STRIP)的方式，畫出球體的vertex，然後把矩形的貼圖一個一個切出三角形再map到球體上，這樣就可以做出星球爆炸的效果。於此，第零版也就開工了，我把演出內容分為三個段落，在第一個段落時想像的是探索星空直至起飛的過程，選了很多網路上下載關於太空或飛行器的圖片，一張一張貼上去。一部分的原因也是因為意識到純粹用Processing作繪圖自己沒有辦法做出很複雜的視覺，想試試用貼圖的方式彌補這個部分。第二階段便是星球，透過「變形、顯示一半、炸開、換貼圖」等等方式，去產生畫面的變換。第三階段，原本的設想是遇到外星人，於是便開始放噪音，呵呵很直觀，當時時間實在不夠，於是那個橋段又變回所謂的「Processing Example」，放一些Attractor畫線條，還有做聲波的Terrain。第一次演出之後的心得，還是在很多轉場上的細節問題，也慢慢學會如何在演出時做縮放，太早把自己寫好的視覺一口氣倒出來，也顯得過於廉價，觀眾對演出的耐看度也會降低很多。於是便慢慢修正自己一些做法，保留自己透過Max生成聲音，同時送一個osc訊號給Processing製造視覺的方法，但是把太空梭的圖片雖著演出時間加入移動、旋轉、變色的效果，以此拉長表演視覺耐看的程度。或是取樣更多的圖檔和聲音，以此做出複雜度。之後便拿來作空總的演出。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_23f6a854173449c996f04734b7900419~mv2_d_3360_2100_s_2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png" title="「“ ”媒體藝術學系」開幕演出 2018.11.12" ></figure><p>也是第一次在一個月內演出同樣作品的修正版，把自己上次聽到的缺陷修正，而這次空總演出則是遇到自己第一次碰到的技術問題： 10:3的螢幕畫面，嗚嗚嗚嗚嗚。以往自己都是在1920:1080的情況下設計視覺，以fullScreen(P3D) 的方式輸出畫面，然後把每個要顯示的東西寫在自己覺得適當的位置。但這次一個10:3直接把我打到哭出來。投出來的比例完全不對，視覺看起來扭曲又有很多顯示不到。於是花了不少功夫把很多視覺都是對應到視覺長度或高度。例如直接寫 float(width)*0.1來放在畫面上十分之一寬度的位置等等。也是這次開始知道如何重視所謂演出現場的校正，在code上面預先做好很多可以在彩排時馬上修正的參數。某次在回顧自己空總演出的影片時，發現不管只看視覺或是純粹聽聲音都實在慘不忍睹，但當兩者相輔相成時，卻有種很～奇～異～～的感覺出現。也慢慢讓我開始思考Audio-Visual的本質與自己的發展方向。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_4589b4d20a704432988ab7337b87ed22~mv2_d_5184_3456_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" title="「A/V衝刺班_噪流實習vol.1」 2018.12.08" ></figure><p>這幾年看些演出或派對，Audio-Visual始終有自己優勢與劣勢。上次跟俊輝在訪談時也自己稍微釐清一些細節的部分。一來Audio-Visual需要的準備時間實在過長之外，當影像過於複雜或是重視視覺特效，同時便會失了原有的細緻程度，導致聲音的連動不夠明顯，表演的感覺不夠即時。自己也是在做行為演出時，重新去思考了所謂「表演」這樣事，自己的解讀始終是一種講自己的能量透過設備、聲音、影像、身體、氣場(?)等等媒介，去折射給觀眾，真正在那個狀態下時，觀眾是會感覺得到的，這也是現場演出的魅力。當影像的連動與即時調整的聲音有所關聯，所帶來的感官經驗也會是極為特殊。</p>

<p>於是乎便來到 B1 那次的演出，當初是靖雅的關係讓我認識了俊輝，我們在華山的路邊聊了一晚，也釐清了一些我自己空總那次演出的優缺點還有可以進步的空間。當時能被邀請到 B1 也算了原了自己某部分的新年願望：自己一直很想在Korner演一次 (然後Korner就掰掰了嗚嗚嗚)。這次也是自己很緊張的部分。也因為自己從來沒有在派對場放過，真要做節奏在Max介面上實在是個痛苦的過程，因此一開始對這場表演是十分憂慮的，更何況這一次就是一小時的Set，雖然是個好玩的活動，但是放太爛被砸鞋砸酒這種故事還是把我嚇怕了。猶記那天晚上跟淳俐還有阿芝在台南恐怖旅店樓下聊了很久這件事，還是很抱歉讓他們忍受我的自我撞牆迴圈。最後我把原本三階段的演出內容拉長成了四階段，並在每段加入不同的鼓。同樣透過不同的聲音去增厚聲音的層次。演出當時到了 B1 實在也是一個嚇，B1的投影機狀況，實在有些........微妙，不過也因此就不緊張了XDDD。於是當時視覺也是亂放一通，就好好玩聲音。那次也是養成了「當自己Max的聲音放到沒梗，或是需要轉場時，就轉一下噪音」這種不健康的玩法。過程就不贅述，但至少在沒出大包的狀況下完成了。也玩了一下「藍屏」斷線接著Glitch這種爛招來接歌。黃偉在看完之後跟我說，聲音的質地還是沒有做到很細，而且中頻的東西還是不夠，也讓我下次有個努力的方向。</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_daf518cc256f4fbbaa0dd0675f345327~mv2_d_6000_3742_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" title="「Reentry再入 北藝大新媒系 第六屆畢業展演 開幕『全域通電！Power Up!』」 2019.06.14" ></figure><p>最後一次是不到兩週後的畢製場，於此同時肝其實已經非常痛了。但總覺得，對這屆學弟妹實在非常非常非常有感情，滿出來到些微作噁那種。也想把自己好好做給盈文看，畢竟這件的前半她也參與了好多我的撞牆迴圈。這次把 B1 的視覺做了更細節的翻新。然後原本一小時的內容壓縮到20分鐘也變得綽綽有餘，可以做很多細節的玩法。也做了一些自動變化的旋律，去修正自己中頻不夠的部分。四面投影其實非常有挑戰性，要先感謝提姆大大與Puta大大的技術支援，讓表演者對演出形式本身沒有後顧之憂，只要開開心心送 4K 畫面過去就好。也謝謝葉港雪中送炭的 4K 螢幕。這次做環場投影的玩法也很簡章，就是把自己的視覺分成四個部分，放在一個4K的畫面送過去。他們會把頂端的 3840 pixels 切成四個960x960 pixels。也是因為剛好聲音在 B1 那次就已經大致底定，這次變花很多時間在做出四個面不同、相同、合併、切換的效果。例如讓星球從四個畫面中間跑動之類之類。或是併了兩個畫面在做搜尋的效果等等。整個發展變成了「星空的搜尋」->「星空、星座」->「星球爆炸」三個階段。噪音的部分就是銜接著之前大爛招，當作一個轉場或補足過於乾淨的數位聲音的底噪。而前面提到旋律的部分，我也讓他隨著爬音，去描繪去星空的線條。除了我的 Signal Vector Size沒有開飽，一些聲音整個歪掉之外，其實整場演出都很快樂的！</p>

<p>最後想切回原本的主題，Lift-Off。當初看到那支震撼的影片，記憶中有個部分是跟提姆他們在打Over Watch的時候也有聊到，就決定這件就在此收尾，送給他們。至今實在無法想像 Elon Musk 有辦法讓火箭推進器「降落」，這樣的發明完全顛覆了我對太空旅行的想像，也讓自己說不定在有生之年真的能上去一次。星空一直是個很好做出 Audio-Visual 的主題。1968年，當太空人 Bill Anders 拍下了一張地球的照片，也開始了 NASA 以影像作為宣傳的手法。於此開始，大量關於宇宙的影視產物也隨之而生。在此也推薦大家看看科普頻道 Kurzgesagt，用Motion Graphic談了很多科學科技等等的內容。也因為這樣的原因，有了非常多的視覺符號可以直接挪用或參考。在此之上，加油添醋上自己的想像，這件表演也就這樣完整了。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_d4e3784150384c73b2c426cf0a92b76c~mv2_d_5939_3959_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" title="「Reentry再入 北藝大新媒系 第六屆畢業展演 開幕『全域通電！Power Up!』」 2019.06.14" ></figure><p>也附上最後一次演出的Code，每一次演出我都會把code存一次 Release</p>
<p><a href="https://github.com/aprilcoffee/lift-off" target="_top" rel="noopener">https://github.com/aprilcoffee/lift-off</a></p>

<p>下一件？就拉回自己的創作脈絡，想一樣慢慢透過一次次演出，去回去談我對於網路與連接的想法。</p>]]></content:encoded></item><item><title><![CDATA[Raspberry Pi 移位暫存器 (shift register) 控制 / 七段顯示器使用]]></title><description><![CDATA[本篇來寫寫當初在月津港(現在在台北數位藝術中心展覽的數位藝術家)很猛的架結構的林瑜亮、跟負責電路板製作焊接(月薪很高小公主)李翎暄跟很廢的我，含辛茹苦的花了18萬的裝置。如何Hardcore的使用python GPIO功能控制移位暫存器，python...]]></description><link>https://www.liutingchun.com/post/raspberry-pi-shift-register</link><guid isPermaLink="false">5c8e06a4592225001c3e9841</guid><category><![CDATA[technique]]></category><pubDate>Sun, 17 Mar 2019 10:10:03 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_3386eacc14aa498a9cba779f92284edc~mv2_d_4032_3024_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p>本篇來寫寫當初在月津港(現在在台北數位藝術中心展覽的數位藝術家)很猛的架結構的林瑜亮、跟負責電路板製作焊接(月薪很高小公主)李翎暄跟很廢的我，含辛茹苦的花了18萬的裝置。如何Hardcore的使用python GPIO功能控制移位暫存器，python GPIO的code部分就不多做說明，可以看前面幾篇文章轉換成Arduino，然後這篇也會稍微解釋Latch, Clock, Data三個名稱，以及很簡單很簡單的在這邊使用位元運算。我很廢在此拋磚引玉，還請大大指正。</p>

<p>適用晶片是TPIC6C594，還有74HC595或各種場合燈節超級萬用的燈條WS2812也可以使用同樣方式(還有還有其他的移位暫存器晶片，例如可以控制16個輸出的STP16C596，只是我沒用過不多說)</p>

<p>(這篇先私心問一下 Wix SEO有沒有有經驗的人會用ＱＱ 我發現在wix寫的blog，google都搜不到)</p>

<p><a href="https://www.liutingchun.com/segmentary-moonlight" target="_top" rel="noopener">https://www.liutingchun.com/segmentary-moonlight</a></p><figure><img src="https://static.wixstatic.com/media/4eb1dd_3386eacc14aa498a9cba779f92284edc~mv2_d_4032_3024_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>直接控制移位暫存器的好處，是如果沒有適當library(如Arduino的FastLED或Adafruit_NeoPixel)才需要使用。另外如果使用arduino firmata的話也可以用這種方式控制。就可以直接在processing呼叫arduino使用ws2812做mapping唷～～</p>

<p>TPIC6C594非常類似74HC595，只是當需要驅動LED的電壓高於5V，就可以使用這片晶片。邏輯電路的部分我就跳過啦(因為我也看不懂)，直接說明code的部分。因為TPIC6C594非常類似74HC595除了可以供更高壓的電流外，我也忘記差別，希望大大指證，所以下面就以74HC595代稱並說明。使用74HC595這種晶片，可以簡單的使用3個pin腳便可以控制八個燈光/元件，當然進行串聯之後便可以控制更多的元件。</p>
<h2>Pin腳們的說明</h2><figure><img src="https://static.wixstatic.com/media/4eb1dd_7b25c618bce2424999bbc24786271a16~mv2.png/v1/fit/w_1000,h_988,al_c,q_80/file.png"  ></figure><p>74HC595基本上上頭有16個腳位，分別是DS、SH_CP、ST_CP、Q0-Q7、Q7' ，還有 VCC、GND、OE跟MR。</p>

<p>DS是Serial data input，就是負責給予Data的腳位。</p>
<p>SH_CP是Shift register clock pin，也就是Clock Pin。</p>
<p>ST_CP是Storage register clock pin，作為Latch Pin。</p>
<p>基本上只要使用這三個pin腳，便可以操作七個以上的燈點～～</p>

<p>Q0-Q7是變成接上需要控制的燈或是七段顯示器的八個燈點(包含小數點的小燈)，Q7' 可以作為串接的pin腳，後面再作說明。</p>

<p>VCC跟GND，恩.....就是VCC跟GND，請接到供電跟接地的地方。</p>
<p>OE是Output Enable，設成低電位時，便可以允許訊號輸出，在連接七段顯示器時，直接與GND即可。</p>
<p>MR是指Master Reset，設為低電位時，會清除暫存器中所有資料。暫時不會用到，放旁邊。</p>

<p>串連多個74HC595的方式，便是把Q7' 接到 下一個74HC595的DSpin腳，然後並聯SH_CP, ST_CP兩個pin腳。就可以多個輸出囉～～(記得下一顆七段顯示器的GND也要併聯近前一顆的GND喔)</p>
<h2>74HC595初始化的部分</h2>
<p>Arduino有個函式叫<strong>shiftOut(dataPin, clockPin, MSBFIRST, low_Byte);</strong>，可以很快地做好這件事，只要開關latch就好，方便快速，但小弟白痴沒用過就跳過不說明，如果想要快速的arduino code，後面我會補上，這邊直接進python的code。</p>

<p>如果只有使用單顆的74HC595，控制的方法就十分簡單。</p>
<p>首先我們先initialize所有的pin腳。</p><blockquote>segmentLatch = 23
segmentClock = 24
segmentData = 25  </blockquote><p>將所有想要輸出的數字做編號以及建成變數，基本上七段顯示器每顆燈的編號如下。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_ec30c34a1b724964b37876e9fda6c675~mv2.png/v1/fit/w_240,h_230,al_c,q_80/file.png"  ></figure><p>我們可以看到對應的英文，便可以由此建立變數。為了方便我們使用移位暫存器時同時將一卡車位元(一顆七段顯示)送進去，我們要將這些英文對應成正確的位元組。</p>
<p>舉例來說數字1便是B+C，數字7便是A+B+C</p><blockquote>a = 1 << 0    
b = 1 << 6    
c = 1 << 5    
d = 1 << 4    
e = 1 << 3    
f = 1 << 1    
g = 1 << 2    
dp = 1 << 7</blockquote><p>「<<」是位元運算中推一個位元的意思。<<6則是推6個位元，天呀我不知道這篇怎麼解釋又懶得畫圖。</p>
<p>舉例來說假使這邊有個位元組</p>
<p>00000000</p>
<p>當我寫下 1 << 2 時便會將1(正)推兩個位元，就成了</p>
<p>00000100</p>

<p>之後我們需要用到「且」這個運算子(|)，來組合我們得到的位置。</p><blockquote>segments = 0 //首先建立segment變數來儲存要送的data<em>
if number == 1:
        segments = b | c
elif number == 2:
        segments = a | b | d | e | g
elif number == 3:
        segments = a | b | c | d | g 
elif number == 4:
        segments = f | g | b | c 
elif number == 5:
        segments = a | f | g | c | d
 elif number == 6:
        segments = a | f | g | e | c | d
elif number == 7:
        segments = a | b | c 
elif number == 8:
        segments = a | b | c | d | e | f | g 
elif number == 9:
        segments = a | b | c | d | f | g 
elif number == 0:
        segments = a | b | c | d | e | f 
else:        segments = 0</em></blockquote><p>且的運算組，可以將兩個位元作且運算，下面附圖表ＸＤＤＤ</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_673f21f2538a4640991d535f8ae83696~mv2.gif/v1/fit/w_143,h_103,al_c,q_80/file.png"  ></figure><p>舉例來說：</p>
<p>a(1<<0) 在我們剛剛的data assignment之後，視為00000001</p>
<p>b(1<<6) 在剛剛建立成01000000，c(1<<5))在剛剛建立成00100000</p>
<p>當我們把a,b,c三個組合做了且運算，便是以下運作邏輯</p>
<p>00000001 |</p>
<p>01000000 |</p>
<p>00100000 |</p>
<p>----------------</p>
<p>01100001</p>
<p>對於七段顯示器而言，1便是所有要亮的點，0便是不亮的，我們便會形成數字「7」</p>
<p>以此方式我們便建議好了各種輸入方法的變數，當然也可以以個人使用自行斟酌～～～</p>
<h2>開始輸出資料進去</h2>
<p>開始輸出時，我們先latch拉至低電位，便可以送data進去，再把latch設為高電位關起來～～</p>
<p>而每一次送出一個位元時，我們必須把clock設為低電位初始化，送一個值，再把clock設為高電位。把這個值往前推一個位元。</p>

<p>Latch在此指的是便是整個晶片接收資料的開關。</p>
<p>Clock則是每一次設置為高電位時，便會推送一個值到下一個位元，以此來說，當我串接一大堆的74HC595我便可以不斷開關clock把所有數字一直一直推送到下一個暫存器。</p><blockquote>GPIO.output(segmentLatch, GPIO.LOW)
n = 0 
while n < 8: 
<em>        </em>GPIO.output(segmentclock, GPIO.LOW) 
<em>        </em>GPIO.output(segmentdata, segments & 1 << (7 - n))
<em>        </em>GPIO.output(segmentclock, GPIO.HIGH)
        n += 1
GPIO.output(segmentLatch, GPIO.LOW)</blockquote><p>這邊的解釋有點玄，我們就先以「7」這個數字(01100001)來說明</p>
<p>首先設計 n = 0 初始化</p>
<p>跑一個當n不小於8時會停止的回圈每次不段開關clock</p>
<p>segments & 1 << (7-n)這個運算式，便是一次一次把下一個數字送去data</p>
<p>這邊有個且運作子(&)，便是做且運算，我們一樣附圖耶～</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_51a5ae2a3d8e4172a5d05e3959d04ec8~mv2.gif/v1/fit/w_143,h_103,al_c,q_80/file.png"  ></figure><p>剛開始 segments 為 01100001</p>
<p>第一次跑回圈時n==0，我們便會將1 << (7-0)，得位元組為10000000</p>
<p>01100001 & </p>
<p>10000000</p>
<p>-----------------</p>
<p>00000000</p>
<p>便是我們送進去的第一組資料</p>

<p>第二個數字為n==1 我們便會將 1 << 6，得位元組01000000做且運算</p>
<p>01100001 & </p>
<p>01000000</p>
<p>-----------------</p>
<p>01000000</p>
<p>便是我們送的第二組資料。</p>

<p>如此一來，我們便可以送入這些資料之後迴圈變會結束。</p>
<p>00000000</p>
<p>01000000</p>
<p>00100000</p>
<p>00000000</p>
<p>00000000</p>
<p>00000000</p>
<p>00000000</p>
<p>00000001</p>

<p>而七段顯示器便會得到這串數字 01100001 視為 「7」</p>
<p>如此一來，我們便可以寫出很快速的一套function來負責解釋我要送的數字。</p>

<p>而當我們需要串接更多的數字時，我只需要不斷的呼叫這套函式，他便會送入不同的74HC595當中。每次呼叫時便會完成一顆七段顯示器的顯示。</p>

<p>附上當時的code，寫了一些函式來執行不同的效果，包含當我收到數字10的時候，會跑隨機的效果等等</p>
<p><a href="https://github.com/aprilcoffee/SegmentaryMoonlight/blob/master/source/mu.py" target="_top" rel="noopener">https://github.com/aprilcoffee/SegmentaryMoonlight/blob/master/source/mu.py</a></p>


<p>附個很隨便的影片</p><a href="https://vimeo.com/324791977">https://vimeo.com/324791977</a><p>(紅色小光段版本是用Arduino Mega硬幹的，因為很酷所以想放一下，但是code完全不一樣)</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_6f5c193c2808446bb77995688f32161b~mv2_d_3888_2592_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><figure><img src="https://static.wixstatic.com/media/4eb1dd_8f2574ee3a384d79a224cb20f25692a2~mv2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure>]]></content:encoded></item><item><title><![CDATA[Raspberry Pi 互動影片切換與播放]]></title><description><![CDATA[這篇來談談近期如何使用 Raspberry Pi 進行互動的影片切換播放。一些用詞上如果有錯誤還請閱讀的大大見諒，並留言幫助我提出修正以分享正確資訊給更多朋友。另外附上上次忘記提及的小小功能，Raspberry Pi最討人厭的小閃電符號移除。 這篇文主要談談如何使用...]]></description><link>https://www.liutingchun.com/post/raspberry-pi-video-switching</link><guid isPermaLink="false">5c486a45978c35001c412b09</guid><category><![CDATA[technique]]></category><pubDate>Wed, 23 Jan 2019 14:49:01 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_c8b9c468c85b427c911c6ef70fc26633~mv2_d_3360_2100_s_2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<p>這篇來談談近期如何使用 Raspberry Pi 進行互動的影片切換播放。一些用詞上如果有錯誤還請閱讀的大大見諒，並留言幫助我提出修正以分享正確資訊給更多朋友。另外附上上次忘記提及的小小功能，Raspberry Pi最討人厭的小閃電符號移除。</p>

<p>這篇文主要談談如何使用 Raspberry Pi 透過 python 來進行電子控制，以及影片播放，關於馬達運作以及GPIO輸出的部分會先跳過，主要講input，開發環境在Python 2.7 上，都是內建在RPi裏頭，我習慣的撰寫方式是使用vim，然後利用python的GPIO library進行互動的部分。透過subprocess的方式，開啟omxplayer來播放全螢幕影片。最初建立這樣的架構時是使用在<a href="https://gunter292.wixsite.com/gunter/copy-of-moonlight-segment" target="_blank" rel="noopener">林瑜亮的作品</a>上，為了方便展出不使用電腦，便利用Raspberry Pi 同時當播放器與互動的控制。作品運作技術大致上來說，便是有兩段不同的跑步小人動畫，以投影機放在線性馬達的方式隨著投影機移動，每當線性馬達抵達其中一端(以微動開關觸發)便會觸發馬達往另一個方向移動，並且切換影片，千言萬語無法形容作品，瑜亮下個月會在台北數位藝術中心展出，可以直接去看作品 <3</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_3f8ef3988dba403bb7850d50376fe759~mv2_d_2448_3264_s_4_2.jpg/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>一般會談到為什麼不使用Processing或Arduino來進行簡單的互動prototype，主要的原因在於Processing在Raspberry Pi上必須使用「GL Video」這套Library來跑影片，然而執行效率實在堪憂，為了給自己一點挑戰，便嘗試把互動的部分組合影像。並使用omxplayer來代理processing播放影片的角色。</p>
<p>看過前篇的朋友應該已經做完了setup但是這邊再重複一次。在Raspberry Pi的terminal上，記得要先安裝以下套件來播放影音檔</p><blockquote>sudo apt-get install omxplayer</blockquote>
<p>當時基本的code都有放在github上頭：</p>
<p>https://github.com/aprilcoffee/autoVideoplayOnRaspberryPi</p>
<p>這邊就來稍微談一下如合撰寫簡單的GPIO程式，基本上會稍作與Arduino在撰寫習慣上的不同。使用的範例是之前瑜亮的作品的部分，<strong>控制馬達移動的同時，在觸碰到兩個不同的微動開關會進行影片切換。</strong></p>

<p>在Arduino上，基本必須在 setup() 做初始化 (initialize) 後，在 loop()中撰寫執行內容。一般來說，製作互動影片不管觸發的感測器是什麼，通常是loop()中讀取感測器之後，以Serialport的方式送至processing去切換影片。本篇文主要有兩段撰寫需要做說明，一段為如何使用python的GPIO library進行電子控制，和如何以python播放影片。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_08964e75f0bf41eab840a367f9ab39e3~mv2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>在了解Processing與Arduino播放方式之後，我們進入基礎的GPIO撰寫。</p>
<p>首先必須透過terminal在執行檔案的資料夾去新增一個python檔案。</p><blockquote>vim videoplayer.py</blockquote><p>python的編寫方法並不使用大括號來分層，全部使用縮排的方式(tab)來表達層級。</p>
<p>一開始時我們需要先呼叫幾個基本的函式庫來進行運作GPIO以及影片播放。</p><blockquote>import RPi.GPIO as GPIO
import time, os, signal, sys
import subprocess
import multiprocessing</blockquote><p>這幾行除了呼叫GPIO之外，我使用subprocess的方式去開啟影片。</p>
<p>首先必須先初始化GPIO的模式以及宣告pin。</p>
<p>GPIO有兩種模式：</p><blockquote><pre>GPIO.setmode(GPIO.BOARD)
GPIO.setmode(GPIO.BCM)</pre></blockquote><p>這兩種不同模式的差異在，BOARD是以排插對應的編號，而BCM是系統排的GPIO編號，我習慣使用BCM原因在於我不會誤用到5V GND等等錯誤的位置。在此附上編號的排序圖(Raspberry Pi 3適用)。中間的那排數字代表使用BOARD模式時對應的號碼。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_ed6893fb609f4325841d16a9047edaae~mv2.png/v1/fit/w_1000,h_341,al_c,q_80/file.png"  ></figure><p>接著便是宣告按鈕變數(或感測器位置)，以及宣告幾個數字用來存取感測器讀取到的值，這幾行的用意與Arduino中使用以下用法相同。</p>
<p>int l_btn = 0;</p>
<p>int r_btn = 0;</p>
<p>pinMode(23,INPUT_PULLUP);</p>
<p>pinMode(24,INPUT_PULLUP);</p><blockquote>l_btn = 0
r_btn = 0
GPIO.setup(23,GPIO.IN,pull_up_down=GPIO.PUD_DOWN) GPIO.setup(24,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)</blockquote><p>可以發現宣告變數的部分，python並不需要事前做型別的宣告，不用在告知變數視為int或char，直接assignment的值為初始化的型別。</p>

<p>而因為python中沒有loop()這樣的結構，在運算的部分，我們需要使用一個 while True: 來包著所有執行序，在期間會不停的執行。因為這次設計的結構是兩支影片在觸碰不同的開關後會切換，我需要以兩個不同的函式來包含這樣的行為。def在python的語法中為宣告函式的意思。簡而言之這樣的寫法在arduino中便是如此：</p>

<p>void goright(){</p>
<p>         r_btn = digitalRead(23);</p>
<p>         delay(0.1)</p>
<p>                   if(r_btn==0){</p>
<p>                   r_btn = digitalRead(23);</p>
<p>                   }</p>
<p>}</p><blockquote>def goright():
          r_btn = GPIO.input(23)
          time.sleep(0.1)
          while (r_btn==0):
                    r_btn = GPIO.input(23)

def goleft():
           l_btn = GPIO.input(24)
           time.sleep(0.1)
           while (l_btn==0):
                     l_btn = GPIO.input(23)</blockquote><p>因為裝置本身是一來一往，我便只要輪流呼叫不同的函式便可以知道目前應該前進的方向。</p>
<p>附帶一提在這邊有做GPIO.input的範例，要做output的話也十分簡單，以下便可以執行high,low等輸出</p><blockquote>GPIO.output(7,GPIO.HIGH)
GPIO.output(8,GPIO.LOW)</blockquote><p>當我有了兩個不同的函式，我便需要在python中撰寫需要的loop()來確保程式不斷運作。<strong>在goright函式中，偵測開關會不斷運算，當開關不等於0時便會跳出。因此才會是在goright()之後播放往左影片。</strong></p><blockquote>播放往右影片 //剛開始便播放
while True:
           goright()
           播放往左影片
           goleft()
           播放往右影片</blockquote>
<p>接著來談談影片播放的部分</p>
<p>使用RaspberryPi與Arduino最大的不同，在於Arduino運算上是為單執行緒，而RPi可以進行多執行序的運算。多執行緒(multithreading)做個簡單的舉例，便是像我們的手機電腦可以同時進行多件事情，例如我們可以同時在電腦上編寫這篇，一邊開著spotify放自己的音樂，兩件事情電腦是可以同時運作。Raspberry Pi基本上可以做到一樣的事，因此我們可以讓他在控制互動的同時播放影片。但在這邊我們需要引入python的函式庫subprocess來做到這件事，讓執行python時，可以開啟另一條thread播放影片。</p>

<p>回到python的部分，我是以一行程式來播放影片的</p><blockquote>proc1 = subprocess.Popen(args=['omxplayer','--no-osd','--loop','-b','--aspect-mode','fill','right.mp4'])</blockquote><p>以及兩行程式來做關閉影片的動作</p><blockquote>subprocess.call(['pkill','-P',str(proc1.pid)])
proc1.kill()</blockquote><p>這邊稍微幫這幾行做個拆解說明</p>
<p>proc1 = subprocess.Popen(args=['omxplayer','--no-osd','--loop','-b','--aspect-mode','fill','right.mp4'])</p>
<p>首先proc1在python中視為宣告一個變數，型態為一個subprocess，我在開啟這條執行緒之後，輸入的指令為以下，各位朋友可以嘗試直接在terminal中使用這串文字，也可以開啟名為right的影片。(請cd到影片檔案的資料夾，運作python時將影片位置放在執行python的位置)</p><blockquote>omxplayer --no-osd --loop -b --aspect-mode fill 'right.mp4'</blockquote><p>這邊附上omxplayer各個arguments的表列：</p>
<p>https://elinux.org/Omxplayer</p>

<p>--no-osd為不在影片播放時顯示時間或是影片任何內容的資訊</p>
<p>--loop 為重複播放</p>
<p>-b 同 --blank 讓影片常設背景為黑色</p>
<p>--aspect-mode fill 便是把影片強迫延伸至整個畫面大小，並且為全螢幕。</p>

<p>這樣便可以開啟一部影片了！！～～～</p>

<p>而後在切換影片時，我們可以直接刪除他，（如在電腦中按下x按鈕關閉影片）</p>
<p>subprocess.call(['pkill','-P',str(proc1.pid)])</p>
<p>proc1.kill()</p>
<p>當我在python中建立proc1這個subprocess時，系統會給予它一個pid，類似於電腦給予這個thread的編號，我只要直接呼叫電腦強制關閉這個thread影片便可以關閉，然後保持隨手好習慣，將這個變數在python中也刪除掉。</p>

<p>如此便是大致上的影片切換與播放了，在不同時候呼叫不同的subprocess開啟影片，並在需要切換時關閉它，另外附帶一提，有空也可以嘗試同時開啟兩部影片，會有意想不到很酷的視覺效果.........</p>

<p>在此附上完整程式，有問題也歡迎回應。</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_5186c79ebb484bbca79c6dea24d6bf16~mv2_d_1383_1732_s_2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png"  ></figure><p>P.S：使用Raspberry Pi 播放影像最討厭人的部分便是用電警示的小小閃電符號，會在螢幕最上方很討厭的一直出現解決方法其實很簡單。回到terminal中到達/boot/config.txt。</p><blockquote>vim /boot/config.txt</blockquote><p>於文件最底下，加入一行文字。</p><blockquote>avoid_warnings=1 </blockquote><p>以上，祝大家玩得愉快！！！</p>]]></content:encoded></item><item><title><![CDATA[Raspberry Pi 基本使用]]></title><description><![CDATA[因為近期接案使用頻繁(或是幫新銳動畫裝置藝術家林瑜亮於香港布展)，遂做個簡單的資料整理；包含遠端操控、開機自動執行、影片播放、3.5音源輸出消除雜音等等，做個常見的 Raspberry Pi 使用經驗分享。盼能拋磚引玉，得到更多分享與回饋。 隨著 Raspberry Pi...]]></description><link>https://www.liutingchun.com/post/raspberry-pi-basic</link><guid isPermaLink="false">5c40303b943e2c001cb9f3ce</guid><category><![CDATA[technique]]></category><pubDate>Thu, 17 Jan 2019 08:31:35 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_341b6ac20bdd4ae88c19db1de94d0391~mv2.jpg/v1/fit/w_640,h_478,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[
<p>因為近期接案使用頻繁(或是幫新銳動畫裝置藝術家<a href="https://gunter292.wixsite.com/gunter" target="_blank" rel="noopener">林瑜亮</a>於香港布展)，遂做個簡單的資料整理；包含遠端操控、開機自動執行、影片播放、3.5音源輸出消除雜音等等，做個常見的 Raspberry Pi 使用經驗分享。盼能拋磚引玉，得到更多分享與回饋。</p>

<p>隨著 Raspberry Pi 的價格逐漸親民，運算量也遠大於一代二代，第三代又內附 wifi 晶片，以Raspberry Pi 作為互動裝置的主機板門檻逐漸降低。想說整理一下最近對 Rapsberry Pi 的使用方法，以及一些十分重要的基礎。</p>

<p>本篇文的撰寫有些操作的門檻，基本上不在 command line 的部分多做介紹。使用的皆為 Raspberry Pi 3 以上之型號，包含 Raspberry Pi 3 Model B, Raspberry Pi Model B+。</p><hr><p><strong>Raspberry Pi 3 購買：</strong></p>
<p>建議能購買正版的主板就購買正版主板，價格雖較高但是運作穩定。</p>
<p>台北車站新裝潢完成的天瓏書局，老闆很善心的把RPi3其他設備包裝成一組，價格為親民的2400，包含 RPi3一台，HDMI線一條，16G記憶卡，電源變壓器，散熱片，RPi外殼，滿推薦購買的。絕對沒有業配，歡迎老闆幫我做個折扣QQ</p>

<p><strong>作業系統：</strong></p>
<p>https://www.raspberrypi.org/downloads/raspbian/</p>
<p>作業系統基本上使用官方推薦的<strong>Raspbian</strong>。個人習慣使用2016年中出的raspbian-jessie目前使用上十分穩定，但切記不要開啟官方測試實驗的gpu加速。</p>

<p>基本上作業系統在安裝時有兩種<em>Raspbian Stretch Lite</em>與<em>Raspbian Stretch with desktop，</em>端看使用方式決定下載哪一款，如果純粹作聲音裝置、網路功能，包含無線分享器、藍芽喇叭，可以選擇使用Stretch Lite，如果要使用影像功能，包含影片播放等等，絕對要使用<strong>desktop，</strong>另外加裝Desktop會因為gui的關係導致運算效率降低。<strong>但推薦新手安裝請選擇Raspbian Stretch with desktop</strong>，多了介面多了方便<strong>。</strong></p>

<p><strong>燒錄與連線：</strong></p>
<p>安裝時需先格式化記憶卡，Mac使用者推薦使用兩套軟體，先於<strong>SDFormatter</strong>格式化記憶卡後，以<strong>ApplePi-Baker</strong>安裝RPi作業系統。燒錄完成後，便可以將記憶卡插入RPi開機。</p>

<p>不熟悉terminal的使用者可以先插上一組螢幕和鍵盤滑鼠，切記切記<strong>不能購買藍芽的鍵盤滑鼠，</strong>初始化時是抓不到的。</p>

<p>熟悉terminal的使用者，可以先以電腦分享網路給Rpi，先將電腦連線上無線網路，透過分享網路的方式，走網路線給RPi，在terminal上輸入</p><blockquote>arp -a </blockquote><p>就可以搜尋區域網路內所有ip，找到raspberry pi的ip之後，輸入指令連線，<strong>內建帳號為pi 密碼為raspberry。</strong></p><blockquote>ssh pi@xxx.xxx.xxx.xxx </blockquote>
<p><strong>基本安裝設定：</strong></p>
<p>開機後基本設定，在RPi的terminal中打上 sudo raspi-config 開始做初始化設定，在advance的部分開啟 scp, gpio, ssh, vnc, i2c。將時區設定好，並且將無線網路連線至手機熱點一次之後便會記憶。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_341b6ac20bdd4ae88c19db1de94d0391~mv2.jpg/v1/fit/w_640,h_478,al_c,q_80/file.png"  ></figure><p>開啟VNC之後，便可以在自己電腦使用軟體 VNC Viewer 連線ip直接操作RPi的桌面。</p>
<p>https://www.realvnc.com/en/connect/download/viewer/</p>
<p>RPi上不需要另外安裝下載，再advanced options設定時便會自動安裝。</p>

<p><strong>系統套件安裝：</strong></p>
<p>接下來是最為重要的系統套件部分，在此推薦幾個非常重要的套件。</p>
<p>首先先在terminal 輸入指令同步官方套件庫的資訊，並且更新所有現有套件。</p><blockquote>sudo apt-get update </blockquote>
<blockquote>sudo apt-get -y dist-upgrade</blockquote><p>更新完畢後，開始安裝套件，以下有幾個推薦套件使用。可以以下指令來安裝</p><blockquote>sudo apt-get install (欲安裝套件名稱)</blockquote><p>推薦套件包含，omxplayer, vim, git. 這些都是必要的套件，但是不像python或vnc官方已經內建好了。</p>
<p>（註：內建python視版本而定，大部分是python 2.7，如果需要python 3需要另外下載）</p>


<p><strong>清除音源線雜訊：</strong></p>
<p>許多使用RPi作為聲音裝置的好朋友，時常遇到一個問題，因為3.5音源線輸出的聲音包含許多雜訊，因此常另外購買一張usb音效卡輸出聲音，其實這問題非常好解決。只要到 /boot/config.txt 在最底下加入一行以下指令便可以解決了啦～～～～～</p><blockquote><pre>audio_pwm_mode=2</pre></blockquote>
<p><strong>開機自動執行：</strong></p>
<p>開機自動執行的方法，需要先製作一份shell script寫下開機要做的所有事情。</p>
<p>首先在你需要執行的檔案，不管是puredata或是python或是omxplayer播一支影片，檔案的隔壁新增一個shell script</p><blockquote>vim launcher.sh</blockquote><p>在script中打上需要前往的路徑(我不好的習慣會放在Desktop)，以及要執行的檔案(如autorun.py)。</p><blockquote>cd /
cd home/pi/Desktop
sudo python autorun.py
cd /</blockquote><p>儲存檔案後，在terminal同個位置下輸入以下指令確保launcher檔案可以被執行。</p><blockquote>chmod 755 launcher.sh</blockquote><p>有時運作的檔案有問題時，開機後不會自動跑執行檔，為了保持良好習慣觀測出了什麼問題，可以回到根目錄建立一個logs的資料夾，再指派系統每次自動執行時將輸出的資料(包含錯誤執行的內容)跑到logs的資料夾中。首先建立logs資料夾，再開啟crontab檔寫上欲執行的launcher檔</p><blockquote>cd 
mkdir logs
sudo crontab -e</blockquote><p>在crontab中寫入 <strong>(請記得修改launcher檔案路徑)</strong></p><blockquote>@reboot sh /home/pi/Desktop/launcher.sh >/home/pi/logs/cronlog 2>&1</blockquote><p>這時 sudo reboot 後就會自動執行了！</p>

<p>另外另外如果開機後跑的是全畫面的影片，想要跳出又不知道怎麼辦，但是又沒有透過ssh進入。</p>
<p>可以很暴力的盲打以下指令來關閉。</p><blockquote>ctrl + alt + T
sudo pkill omxplayer</blockquote>
<p>以下大概是Raspberry Pi基本的一些功能。</p>
<p>之後有空再來撰寫 python 控制GPIO的部分，以及如何使用subprocess切換omxplayer來開啟影片。還有如何使用Raspberry Pi架設簡單的無線基地台。</p>]]></content:encoded></item><item><title><![CDATA[身體作為現場的折射（一）]]></title><description><![CDATA[在處理香港展覽的作品論述時， 一直想談談自己身體創作的脈絡。回來讀了讀去年寫的文章，想想還是寫成文字也比較好梳理。最早開始行為的嘗試，最粗淺的應是大二上高嶺格(Tadasu Takamine) 至新媒系作客座教授指導時的《Tomorrow’s...]]></description><link>https://www.liutingchun.com/post/body-as-the-reflection-on-site</link><guid isPermaLink="false">5c403d8808d63c001c9cc1d4</guid><category><![CDATA[works]]></category><pubDate>Sat, 25 Aug 2018 08:35:13 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_11bbd0e1c4674a55b235c8bd64ba5ba6~mv2.jpg/v1/fit/w_720,h_576,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[
<p>在處理香港展覽的作品論述時， 一直想談談自己身體創作的脈絡。回來讀了讀去年寫的<a href="https://www.facebook.com/notes/%E5%8A%89%E5%BA%AD%E5%9D%87/%E7%93%B6%E4%B8%AD%E4%BF%A1/1634555859897079/" target="_top" rel="noopener">文章</a>，想想還是寫成文字也比較好梳理。最早開始行為的嘗試，最粗淺的應是大二上高嶺格(Tadasu Takamine) 至新媒系作客座教授指導時的《Tomorrow’s Torture》呈現，那時的呈現以現在的標準看實在不致稱之為作品，但從那時開始也引導出一種對於現場新的想像。當時的作品很簡單，在高嶺格兩週工作坊的過程中，時常作為同學間口譯的工作，對於翻譯間的落差有了些想法，於是最後呈現時我拿了一支大聲公，挑選了彼得．漢德克的劇本《<em>冒犯觀眾》</em>為文本，用中文與英文交錯對台下的觀眾謾罵。原有的期待，是能在中英文交雜的過程中，挑弄語言間理解與不理解的摩擦。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_acf30e826d984be98dc16f9436e8ccf4~mv2.jpg/v1/fit/w_1000,h_720,al_c,q_80/file.png"  ></figure><p>結果一路罵到袁廣鳴睡著了。 大概是這樣的第一次行為表演。電腦壞掉的時候，影片也一起丟了。那天也遇到了後來影響自己很大的狀況，當時坐在後面樓梯上看夜景的兩個女生，一路聊天，我的聲音越大，他們的聲音就跟著更大，還接著唱歌。我記得後來討論時，廣鳴提到，既然要罵觀眾，為什麼不就轉頭對她們開罵？也是這個原因，在後來的身體表演，也開始注意現場觀眾的狀態，以及自己的表演要如何反應。再下一次身體的嘗試，就是這件跟蔡昉合作的作品，那是大二錄像藝術的期末。那時候跟阿光討論的想法也很簡單，很簡單思考 Moving Image 中，究竟是什麼 Move 了？然後寫了很隨便很大二的論述。</p>
<pre><code><em>影像的本身即因為影格與影格間的堆疊而具有離散性。但同時它卻反映了線性的真實世界，我想用跌倒這樣短暫而確實疼痛的事件，透過反覆至少一百次之後，以每一次的影像剪取數格影格堆疊。質疑真實與影像之間的關係。</em></code></pre><a href="https://www.youtube.com/watch?v=praCnmqs5QA">https://www.youtube.com/watch?v=praCnmqs5QA</a><p>那是第一次嘗試要把自己的身體置入影像中，拍攝的時候，我們用了我的和她的iPhone拍了慢速，跌倒了一百多次，每次摔在地上時，擷取了其中5-10格帶著聲音的影格，對上相同的身體位置，疊加再一起。與一般的Stop Motion不同，在這支影片中，每一個影格都帶著現場聲音的採樣，把現實中3小時的時間壓縮成20秒的動態影像。作品本身觀念之外，那時做身體似乎有種魔力，身體會不停累積疼痛，而在畫面中都是不可見的。也自此開始思考自己的身體是如何成為創作的媒材，還有它的可能性。之後去了一趟布拉格，沒錢沒想法沒設備，就真的開始做行為了⋯⋯ </p>

<p>初抵布拉格美術學院(Akademie vytvarnych umění v Praze)時，是被分配到 New Media II 工作室的，但國際交換生的負責老師建議我參與看看客座藝術家<a href="http://www.dg-c.org/?fbclid=IwAR22iXfZnLapJNSB4VfCl3IpiyP2u79S2S81Sy1GhMav6fASh4nPVQ8qn5w" target="_blank" rel="noopener nofollow"> Christina della Giustina </a>的工作室。那是一間位於市郊的空間，原本是學校其中一間做雕塑的教室，每學期會交換有不同國家教授，學生可以從原本自己的工作室轉換過去一學期。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_bf529e995c8b4105a18fa0aa8d8a587f~mv2.jpg/v1/fit/w_720,h_960,al_c,q_80/file.png"  ></figure><p>Christina 的創作比較多著重在觀念的作品聲音創作，在指導時也比較像朋友，給予的建議多是怎麼想像自己的身體狀態。初到工作室時，教授與助教把工作室中間用紙膠帶圍出一個方塊，並出了第一個課題，贈與工作室中公共空間一個行為 (Gesture)，作為自己使用私人空間的交換。說實話剛開始實也沒什麼想法，手邊也沒有習慣的創作資源 (祥昌興城街什麼的)，看到地上被圍成一圈的紙膠帶，就想起 Bruce Nauman 的作品「<a href="https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.moma.org%2Flearn%2Fmoma_learning%2Fbruce-nauman-walking-in-an-exaggerated-manner-around-the-perimeter-of-a-square-1967-68%3Ffbclid%3DIwAR2mVpFkDvN5rrivkJMQKO6AyoEh4n891tDJRgmAtHBrl-zOof8_rhiCsDs&#38;h=AT1VRMZkmDblYBTPZUbT3sIqQNsqY15qnHgrl9frUC9W_XYycQ5AtB-X0vqTuyA282MAeOd40JtgtBgSAmDupy1AqWpMlM1R9dAC_w-2rz83GZmQ0WkPy6RusSQcOyPMnYbgc9xR8_Q" target="_blank" rel="noopener nofollow">Walking in an Exaggerated Manner</a>」隨手就在往工作室的路上撿起一塊石頭，沿著地上的膠帶線敲打，這大概是在布拉格創作的第一個實驗。</p>
<a href="https://www.youtube.com/watch?v=x7DWz_jMtR4">https://www.youtube.com/watch?v=x7DWz_jMtR4</a><p>原本的設計只是沿著路線走完，但慢慢敲打的過程中，會發現自己的節奏以及動作，會與膠帶的紋理交互影響，遂把膠帶當作譜面，刮痕、斷面、磨損、去閱讀膠帶來完成行為，在途中被同學擋道時，想起了自己在先前表演時缺乏與現場的互動，便把石頭丟給同學讓他敲過他的身體範圍。當每個同學都給予空間自己的創作之後，我們被引導的討論環繞在彼此之間的關係，誰的聲音與誰的行為有了交錯，而教授與助教也親自創作，給予自己對於這個空間的想像，這也引導到了我們之後的延伸。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_997cbf90007c44358bb707baaca0d2e0~mv2.jpg/v1/fit/w_960,h_720,al_c,q_80/file.png"  ></figure><p>環境中也有了不同同學帶來行為的結果，第二週開始，我便買了好幾卷的紙膠帶，把原本的空間做出延伸，拉出公共空間的範圍，然後再重複使用石頭敲打與取樣。把紙膠帶纏在其他同學放置的椅子、石頭、落葉上，依次敲打，上一次作為一個封閉的環，這次則是沿著自己額外拉出，不生成新的空間的「線」。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_ff6eb73a96914d368bdd4353a0dbc388~mv2.jpg/v1/fit/w_1000,h_720,al_c,q_80/file.png"  ></figure><p>第二週之後，大家的創作範圍逐漸擴大，其中也遇到一件有趣的事，如電影抓狂美術館一樣，空間的打掃阿姨，把我們的落葉清的乾乾淨淨整理成堆，還把同學放的筆和石頭擺放整齊。之後的創作大家漸漸開始以「誰的什麼影響出我現在的什麼」為目標開始逐漸延伸，這個空間中所有的物件也成為一件大型創作。</p><figure><img src="https://static.wixstatic.com/media/4eb1dd_cdb203a3d8b7486db2f10903015cb5c2~mv2.jpg/v1/fit/w_960,h_720,al_c,q_80/file.png"  ></figure>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_c82b59985c1c4e8b8e5f099db6034a94~mv2.jpg/v1/fit/w_720,h_720,al_c,q_80/file.png"  ></figure><p>逐漸到了學期末，機制上被要求要做一場 Open Studio 的展覽，而我們的目標也開始從時間性的行為，成為空間中的「展出」。在台灣時跌倒的作品，便成為我想思考的延伸，我想像著要如何濃縮一個時間性的行為成為一個「展出」，如何將整整一小時歷久敲打的過程與痛苦，壓進一個短暫的狀態，更多則，如何將現場的聲音也放進去。</p>
<a href="https://vimeo.com/320003075">https://vimeo.com/320003075</a><p><a href="https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.liutingchun.com%2Fi-kept-repeating-the-unfamiliar-sel%3Ffbclid%3DIwAR3oQDnXVEskitej4I_YDjmQ_bvpzEs1ZXWnoIxRKU1Dza-MLN1WLrkoHd8&#38;h=AT1qsdyAKOMpwVk1OzH9C-9ai1bzd161vr8RcR-Qic_lTAAkKm8xkVcUpo8eseCnVYgAq4LFdHLkxPevoXrGmAUPfQhY2S_-x1jBsklx5ITiuoSL-OwNqOeEYyh-hd2Pge7bwuo7vUgl-KrCrSW35BIK" target="_blank" rel="noopener nofollow">作品論述</a>是這樣寫道的： 「 作品是極為簡單的動作不斷重複，試圖達成相同的結果，以及產生一個聲音，在重複的過程中記憶著相同的運動狀態，盡力著讓其達到預設的結果。並將他們重疊壓縮成為單一的動作。延續先前作品，透過重複單一動作的壓縮影像討論影像的真實性，和現實時間與影像時間的關係，並納入現場聲音，將空間的音場也進行壓縮。這次我拍攝了數個單一的手勢(Gesture)數百次，並將每個動作取下固定幾個影格與聲音片段，再將其堆疊並壓縮成單一的動作影像。企圖建立單一動作的秩序，於此同時身體所特有的失準也將顯現，而現場的聲音與身體的動作所觸發的聲音，也是與自己身體的對話。」</p>

<p>我常在想像每個身體的動態，以及其所延伸的痛處是如何被記錄的，便用這樣的方式完成，最初在製作「跌倒」的影像時，也並未將聲音列入思考，一直是在剪輯時才發現這種剪輯方式特有的魅力，不同於一般 Stop Motion 動畫，除了畫面本身，聲音也同樣被壓縮進去。也因此嘗試以這樣的方式，把數百次的敲打都置入其中。最後展出時把喇叭藏在後面的水溝中，寫了一支會隨機觸發敲打影片的 processing 影像播放程式。隨機的將整個敲打的聲音擴散在整個充滿迴響的空間中，也算是給自己在捷克創作的一個收尾。</p>

<p>在事後的討論中，我常在思考把身體置入影像中的感覺，當它被編輯、複製、貼上、重整，身體最終成為圖像的一部分，而從空無一物的畫面中，直至被敲打的當下，也被以教授以宗教性這樣的名詞討論，表演如何再現？而身體在其中的能量是否被抹平？如果說破碎的身體中，我們如何在空間中生產聲音，我們如何完成一個目標，又自我在當中所代表的意義又是什麼？而身體再現在現場的同時，與自身的表演，似也做了切割，我們在閱讀這個影像時，所看見的是一隻不知道從何而來的手。沒有了標的以及理解其所生產過程的指涉。</p>

<p>原本沒有預期會寫成這篇文章，才想起自己跟何育葦合作的作品(真的真的很感謝那件作品)，以及在捷克比對台灣脫衣服過程的想法。一些心理狀態，我想這些就留至下一篇再來細談。</p>]]></content:encoded></item><item><title><![CDATA[瓶中信]]></title><description><![CDATA[瓶中信 ——與任何遲抵的彼方 或許是期末迫於撰寫太多描繪自身的文字，而也恰到一個時間點，我想開始整理近期的一些想法(當然俊吉老師勸誘了我跟韋霆還有蔡昉一整學期去整理好自己的論述也是其中一項因素)。關於網路、關於時間、關於網路上的時間、關於現實中的時間、關於數位中的時間、...]]></description><link>https://www.liutingchun.com/post/messageinthebottle</link><guid isPermaLink="false">5c399501486959001c6441cd</guid><category><![CDATA[works]]></category><pubDate>Wed, 08 Nov 2017 08:00:24 GMT</pubDate><enclosure url="https://static.wixstatic.com/media/4eb1dd_e0102bb37d434178bba8f40458229562~mv2_d_3809_4333_s_4_2.png/v1/fit/w_1000,h_1000,al_c,q_80/file.png" length="0" type="image/png"/><dc:creator>Ting Chun Liu</dc:creator><content:encoded><![CDATA[<blockquote><em>瓶中信 ——與任何遲抵的彼方</em></blockquote><p>或許是期末迫於撰寫太多描繪自身的文字，而也恰到一個時間點，我想開始整理近期的一些想法(當然俊吉老師勸誘了我跟韋霆還有蔡昉一整學期去整理好自己的論述也是其中一項因素)。關於網路、關於時間、關於網路上的時間、關於現實中的時間、關於數位中的時間、數位中的身體。以及系展時談的「我們的身體如何認知數位？」。還記得跟韋霆提到了，不知為何近期不斷接觸好多新事物與知識，我用「這些網路什麼的」來形容的範圍。於是最近開始把幾項關於網路的小實驗都慢慢打成文字，或許冥冥中自有注定，或許我們找到了新的關鍵字，或是同溫層漸漸往不同方向移動，我不知道，但我對於這樣的未知，充滿期待與憧憬。</p>
<pre><code><em>I believe that the internet is becoming a planetary meta-organism, but that it is up to us to guide its evolution, and to shape it into a space we actually want to inhabit -- one that can understand and honour both the individual human and the human collective, just like real life does.  --Jonathan Harris</em></code></pre>
<p>一項3/16開始進行的計畫，或說場實驗更為恰當。至於會持續至何時？至今我亦尋不著端倪。最感意外的部分，是在過程中不斷連結新想法與狀態；無論是與人討論而生的辯證，亦或因生活經驗所形塑另一種觀看的角度，它再脫離了初衷，似也拓出了一條陌生的道路。一如所有對話，這篇文章一樣也會充滿謊言，但謊言不也是為了掩蓋事實的一種真實嗎？也很感激過程中有聊到這場實驗的夥伴，無論是否是酒後憨語(笑)，或聊及系展作品的朋友，種種生命經驗於此交織。而時間則是事件發生的註記。</p>
<figure><img src="https://static.wixstatic.com/media/4eb1dd_a1475ec8c4414d0b9c4268796d5d6b43~mv2.jpg/v1/fit/w_720,h_894,al_c,q_80/file.png"  ></figure><p>用嘴說的部分，尚能順暢，但以文字整理時卻顯窘迫。一切的起點應回到捷克的生活，也解釋過許多次了，僅只是很簡單關於「時差」的狂想，還記得那時刊物組的文章常被友儀<a href="https://www.facebook.com/tnuanma/posts/1836978266537825" target="_top" rel="noopener"><u>催稿</u></a>，三篇關於光的文章、或電子藝術節的心得；文字的撰寫實為一項甜美而苦痛的過程，被催稿更是；當時收到何月何日幾時幾分交稿之期限，突然意識到我們共用了同樣的時間，卻使用不同的時間註記。而這樣的疑惑到回國之後更顯混亂，平日習以為常之狀態，特別是在網路上與人對話的關係，一瞬被反轉。本在網路上對話的對象成了真實的人，原本他們的夜晚是我的白天，原本起床便可看到他們一整天白天活動的貼文。所有關於時間的註記與習慣被徹底破碎。這也是一切的開端。而我想了解，我想了解究竟在資訊世界中有無確切的時間存在？當我們藉由網路共享同一時間軸與資訊交換的媒介的同時，其中的時間應當怎樣去註記？</p>
<pre><code><em>欲說還休；欲說還休，卻道天涼好個秋。-醜奴兒</em></code></pre><p></p>
<p>那時顏晴問我什麼是「數位遺產」，有沒有相關的書可以閱讀？至今仍未整理予她。臉書上的文章，是否也構成為數位遺產的條件？我一直在想，究竟在臉書上發文的意義是什麼？純然的分享、或想在生命中註記特定事件的發生？有些人不想讓外人了解太多的自己，而選擇極少發文，僅只對自己喜愛的貼文按讚。有些人天天發文，如有多不完的話、滴滴答答的噴濺在社群網絡中。在我的想象中，似乎也沒有一個絕對的答案。在臉書上的文章一篇一篇來去、浮光掠影，真的有人注意過其中的內容嗎？長篇大論與短篇簡談，在表述自我的意義上有沒有任何差別？或是其實這一切都是如此一無所謂，重點則停在發文的瞬間與慾望，所有在臉書貼文大海之上漂流的內容都失了意義。只因有了發文的想法，不需具有發文的內容，千言萬語與一句話的力量在慾望的滿足感上是相同的，都是求得最終在海量的貼文中載浮載沉。我不禁想像著，能否有個方式去表達一種無以名狀的表述；以一個貼文的形式去訴說「貼文」這件事本身。Thu 20:58:34，短短一行字，在貼文當中不具有任何意義，卻同時達成了「貼文」的這項目的。發文的時間被記錄在文章當中，而不只是臉書內建流動的「32分鐘前」。這篇文章同時具有意義也同時在內文中沒有文字的意義。當有千言萬語想要說，不如說出一席毫無關係意義的話語。</p>
<pre><code><em>你們兩個都是陰鬱而又謹慎： </em>
<em>人啊，無人嘆過你的深淵之底； </em>
<em>海啊，無人知道你深藏的財富， </em>
<em>你們把秘密保守得如此小心！  </em>


<em>--波特萊爾 《人與海》</em></code></pre>
<p>「Mon 01:56:33」僅只是一篇貼文，內文本身註記著自身呱呱墜地的精準時刻。自那時起，它便在網路社群這片汪洋載浮載沉，等待著任何人不經意的拾起。像一封瓶中信，唯瓶身只註記了生產日期，打開瓶子卻是寂靜的空洞，而拾起的人，便不自覺著尋找著故事或事件來填補那項空洞，但內容物對我始終不是絕對。反而是瓶子本身，才是我意圖去形塑的狀態。說來矯情，我當它是一種浪漫，一種自身在海洋中載浮載沉的浪漫。每隔一段時間丟出一個瓶子。好似藉由瓶子本身宣示著身在海中之感嘆，卻也不想就此講死，仿佛仍舊享受著漂泊⋯⋯。</p>
<h2>後記：</h2><pre><code><em>且讓我們以一夜的苦茗，</em>
<em>訴說半生的滄桑，</em>
<em>我們都是執著而無悔的一群，</em>
<em>以飄零做歸宿 。</em>


<em>-簡媜〈四月裂帛〉</em></code></pre>
<p>這篇文章整整寫了三週，對於詞彙的選用相較於高中時實為生疏，而想法的表述也遭遇了字詞不足的障礙，實為遺憾。這段實驗的過程是很愉悅的，最有趣的部便是與人的互動，去傾聽那些無法預期的隨機性，以及人們的臆測。同時自己也很享受詢問別人對此的想法。我想最根本的開端，還是對於歐洲的同學們，上頭看到的時間並不是他們所身處的時間。但漸漸的，自己反而形成一種「我想發文」於是來發一篇文好了的心態。很多時間發文的狀況與原因並不一致，對自己也沒有特意的規定要在什麼樣的情況發文。只能說大部分時間都是情緒上的波動。（以至於很多時候當人問起「為什麼要發時間？」時，我會附和著，然後發了另外一篇）。當然也有很多人有過不同的猜測：「心情不好的時間？」「想抽菸卻沒抽的時間？」「睡覺的時間？」「打工的時間？」「莫名其妙。」。所有的答案或許對或許也不對。這整段過程也是萬分滿足與成長的，藉由與他人溝通的同時，理清自己的想法，並拓展它。我想接著也會慢慢開始整理自己做行為的想法吧。也很感謝所有聽過那艘漂流小船故事的老師或同學。我想讓它持續在大海中探尋，偶而投出那些小小的信標，告訴你們我還在那。</p>
<h2>Tue 01:14:37</h2>]]></content:encoded></item></channel></rss>