Wednesday, July 25, 2018

Perlman / Film Music - Cinema Serenade (帕爾曼的電影琴聲)

Perlman / Film Music - Cinema Serenade (帕爾曼的電影琴聲)

一、資訊

電影:請見曲目
配樂作家: 很多
演奏:Perlman, Itzhak
發行廠商:Sony Music
Perlman / Film Music - Cinema Serenade


二、心得感想

這張基本上沒什麼好說的,帕爾曼加上John Williams還有其他經典電影等於"買買買"。
尤其是辛德勒的名單,還是帕爾曼最對味。
這張的第二首應該算是很常聽到(每次電視跳tango都是拿這首),不過不知道曲名,而這張剛好有機會讓我重新認識這首。第四首的郵差讓我驚豔,害我特別去spotify找整張來聽,以後有機會應該會入手。

三、曲目

  1. 紫色姐妹花(The Color Purple: Main Title)
  2. 女人香(Scent of a Woman: Tango (Por Una Cabeza))
  3. 楊朵(Yentl: Papa, Can You Hear Me?)
  4. 郵差(Il Postino: Theme)
  5. 純真年代(The Age of Innocence: Theme)
  6. 遠離家園(Theme from Far and Away)
  7. 秋水伊人(The Umbrellas of Cherbourg: I Will Wait for You)
  8. 末日四騎士(Four Horsemen of the Apocalypse: Theme)
  9. 新龍鳳配(Sabrina: Theme)
  10. 遠離非洲(Out of Africa: Main Title)
  11. 黑色奧菲歐(Black Orpheus: Manha de Carnaval)
  12. 辛德勒的名單(Theme From Schindler's List)
  13. 新天堂樂園(Cinema Paradiso: Love Theme)

Sunday, July 22, 2018

The Legend of The Pianist ( la Leggenda del Pianista sull’Oceano ) - Italy Version (海上鋼琴師)

The Legend of The Pianist ( la Leggenda del Pianista sull’Oceano ) - Italy Version (海上鋼琴師)

一、資訊

電影:海上鋼琴師
配樂作家: Ennio Morricone
發行廠商:Sony Music
The Legend of The Pianist ( la Leggenda del Pianista sull’Oceano ) - Italy Version (海上鋼琴師)


二、心得感想

這張基本上有名到我都不想寫什麼介紹了XD,不過秉持著紀錄所有我買過得專輯,所以還是隨手打一篇。這片在買之前裡面的音樂幾乎都已經在各個角落聽過了,即使電影只看過一次,在音樂課,在其他專輯(Yo-Yo Ma Plays Ennio Morricone)或多或少經典曲目包括<Playing Love>、<Magic Waltz>、<A Mozart Reincarnated>還是有名又有梗的鬥琴<Enduring Movement>有在接觸電影配樂的朋友都聽過。其中最喜歡的是<Playing Love>、<Magic Waltz>、<A Mozart Reincarnated>,至於鬥琴那首我到覺得還好。其他也有一些較為不有名曲目如帶有爵士風情的<A Goodbye To Friends>等,還有<Tarantella In 3rd Class>也都十分動聽。我覺得這張真的必收。

三、曲目

  1. Playing Love
  2. The Legend Of The Pianist On The Ocean
  3. The Crisis
  4. Peacherine Rag
  5. A Goodbye To Friends
  6. Study For Three Hands
  7. Tarantella In 3rd Class
  8. Enduring Movement
  9. Police
  10. Trailer
  11. Thanks Danny
  12. A Mozart Reincarnated
  13. Child
  14. Magic Waltz
  15. The Goodbye Between 1990 And Max
  16. Goodbye Duet
  17. Nineteen Hundred’s Madness N. 1
  18. Danny’s Blues
  19. Second Crisis
  20. The Crave
  21. Nocturne With No Moon
  22. Before The End
  23. Playing Love
  24. Ships And Snow
  25. Nineteen Hundred’s Madness N. 2
  26. I Can And Then
  27. Silent Goodbye
  28. 5 Portraits
  29. Lost Boys Calling

Arduino: High resolution PWM (more than 8bits),Arduino提高PWM resolution

Arduino PWM(analogWrite)

Arduino PWM是使用analogWrite,但是其有一個限制,也就是PWM resolution只有256,PWM duty cycle的值只能介於0~255,對於一般的應用來說,這個值還可以應付,但是對於高精度的Servo或是馬達,這個值實在是太小了。(請參考analogWrite)。雖然在有些板子Arduino提供analogWriteResolution這個函式(Zero, Due & MKR Family、參閱:analogWriteResolution)可以將PWM resolution提高至12,更高的值內部會做mapping到比較低解析度。至於其他板子(例如:Arduino Mega 2560),則需要第三方library支援(或是自己寫)。

Arduino的硬體PWM極限(Arduino Mega 2560)

以Arduino Mega 2560為例,在其datasheet(link)中提到其"Six/Twelve PWM Channels with Programmable Resolution from 2 to 16 Bits",ATmega2560有12個PWM channel,resolution可為2~16bits。所以其實Arduino Mega 2560硬體可以比Arduino Framework設計的resolution高很多。至於為什麼Arduino官方不用16bits呢,我猜是因為為了保證0~255的限制是可以達成。Arduino Framework的PWM frequency是固定的(16 MHz / 64 / 255 / 2 = 490.196Hz,見Secrets Of Arduino PWM)。

而PWM resolution並不是你想要16bits就可以有16bits的resolution,PWM resolution跟PWM frequency息息相關。在ATmega2560中,Frequecy與系統頻率、timer prescaler(除頻器),還有最常使用的TOP值(限定Timer counter的最大上限)有關。TOP值的大小即為PWM resolution。依據Atmel PWM resolution公式:
PWM resolution = log(TOP + 1) / log 2
 通常要把PWM resolution拉到最高,PWM frequency會很小,這主要看設計時的選擇。其他細部詳情請見ATmega640/V-1280/V-1281/V-2560/V-2561/V [DATASHEET]第17章。

 arduino-pwm-frequency-library

這裡介紹一個第三方library "arduino-pwm-frequency-library",可以在這個網址找到:https://code.google.com/archive/p/arduino-pwm-frequency-library/downloads
,這個libaray的範例中可以提供你在給定的frequency下,PWM resolution的上限。而程式用起來十分簡單如下:


// Arduino Mega,pins 2 - 13 and 44 - 46.

#include <pwm.h>

unsigned int duty = 1; 

//use pin 11 on the mega for this example to work

int led = 11; // the pin that the LED is attached to

void setup() {

  // put your setup code here, to run once:

  Serial.begin(57600);

  InitTimersSafe(); //initialize all timers except for 0, to save time keeping functions

  pinMode( led, OUTPUT);

  SetPinFrequency(led, 10);

  

}



void loop() {

  // put your main code here, to run repeatedly:

  

  while(1){

    pwmWriteHR(led,duty);

    duty+=10;

    delay(100);

    Serial.print("duty = ");

    Serial.println(duty);

  }

}


然而這個library的function會有一些副作用,由於前面提過要改resolution和frequency需要更改Timer的一些設定,其中Arduino使用Timer0作為delay() 這個函是的時序。所以可能會有影響,另外她同時會更改所有Timer的設定,若有使用其他Timer的話要小心。

Arduino Framework裡的digitalPinToTimer Macro

在Trace arduino-pwm-frequency-library時,我發現其呼叫了這個Marco digitalPinToTimer,其實在Arduino Core[github]中還有多類似的Macro像是 digitalPinToInterrupt等(https://github.com/arduino/ArduinoCore-avr/blob/3f63f2975e7183c3254b6794bfcc8f19ca0301c9/variants/standard/pins_arduino.h)這些Macro實做方式為,在同一個header中使用PROGMEM(program space)建表,可知Arduino framework其實裡面可能使用了些program space存放這些表,即便你沒用到這些函式或marco。若是哪天你不小心寫滿了program space可能就是這個問題。(補充:大部分Arduino cpu如ATmega 2560為哈佛架構的RISC cpu,其有獨立的program memory存放code指令和一些const,還有獨立的data memory存放變數。而我們一般的桌機為拆分快取的哈佛架構,到L1或是L2 cache變為哈佛架構。而8051為Von Neumann,data space和program space共用memory (bus))。

Wednesday, July 18, 2018

對MPLAB X IDE產生之專案導入git

MPLAB X IDE產生之專案架構

MPLAB X IDE產生之專案會XXX.x以.x做結尾。常見的檔案樹如下:
.
├── build
│   └── default
│       └── production
│           ├── main.o
│           └── main.o.d
├── debug
│   └── default
├── dist
│   └── default
│       └── production
│           ├── 4013_test.X.production.elf
│           ├── 4013_test.X.production.hex
│           └── 4013_test.X.production.map
├── main.c
├── Makefile
└── nbproject
    ├── configurations.xml
    ├── Makefile-default.mk
    ├── Makefile-genesis.properties
    ├── Makefile-impl.mk
    ├── Makefile-local-default.mk
    ├── Makefile-variables.mk
    ├── Package-default.bash
    ├── private
    │   ├── configurations.xml
    │   └── private.xml
    └── project.xml
可以發現build/default、debug/default、dist/default/底下存有編譯時期產生之檔案,而nbproject/private則存有當前專案於當前系統中實際之相依toolchain路徑。

Git Ignore

有了前面的事實,我們git ignore應該寫成如下:
*/nbproject/private/
*/dist/default
*/build/default
*/debug/default

至少需拔掉編譯時期會產生檔案。此外nbproject下的Makefile相依檔案,如Makefile*, XXX.mk等一定要進入git。

跨OS issue

雖然MPLAB X IDE產生的專案可以輕易在LINUX上與Windows上運行,不過為了紀錄OS資訊,MPLAB X IDE會在Makefile-genesis.properties這些properties檔案中存入作業系統資訊。因此git在這些區域容易出現問題(confilct)。比較好的辦法就是不要跨平台。然而若是仍須跨平台,Makefile-genesis.properties5這檔案可能會造成MPLAB X IDE找不到compiler或是toolchain。因此可以透過MPLAB X IDE  GUI界面,選擇project properties,重新創立properties。

NetBeans git plugin

MPLAB X IDE是以NetBeans為基礎,所以也可以使用NetBeans的git plugin。

Saturday, July 14, 2018

CMake: find_package and custom find cmake (findXXX.cmake)

CMake: find_package and custom find cmake (findXXX.cmake)

我個人覺得這主題寫最好的是這篇,我會建議大家可以看這篇,不要看我寫的XD
https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-To-Find-Libraries

find_package

find_package是CMake中用來找第三方package的command。這command功能是去找到所需第三方package的資訊(版本、include path、library path等),並將資訊存入定好的variable中。find_package會曲找尋CMakeLists.txt所在資料夾下的FindXXX.cmake,或是cmake本身定義好的FindXXX.cmake,通常系統路徑是/usr/share/cmake/Modules下(Arch Linux是放在/usr/share/cmake-版本號/Modules下)。基本上有名的package都已經被定義好了。若是想要知道有哪些可用可以自行去路徑下找,或是用:
cmake  --help-module-lists
查詢。
在CMake中使用find_package通常會使用類似下列參數。

find_package(OpenCV 3.4.1 REQUIRED)
 find_package(package_name version [REQUIRED] [QUIET] ),Version非必要,主要看package敘述。REQUIRED和QUIET主要用於相依性,若package為必要用REQUIRED,若沒找到直接報錯。選擇性用QUIET,通常會用類似下列方式達成選擇性。若沒找到package不會報任何錯誤。
find_package(OpenMP)
if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
透過find_package 定義的-FOUND判斷是否存在。
find_package通常會定義下列四種變數:
  • _FOUND : 是否找到
  • _INCLUDE_DIRS or _INCLUDES : include path,類似gcc -I/path
  • _LIBRARIES or _LIBRARIES or _LIBS : link library 類似 gcc -L/path -l library
  • _DEFINITIONS
當有這些參數後,即可透過一般CMake include或link方式使用,例如:
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_link_libraries (main ${PCL_LIBRARIES} ${OpenCV_LIBS})
等方式使用。

 custom find cmake (findXXX.cmake) find modules

若是CMake沒提供modules就要自己寫find modules啦。
依照前面的敘述,可以知道Find modules最重要的就是取得那四種變數的值。下面以我寫的FindRealsense2.cmake為例。


find_package(PkgConfig)
find_package(PkgConfig)
if(${CMAKE_VERSION} VERSION_LESS 2.8.2)
    pkg_check_modules(PC_REALSENSE2 librealsense2-dev)
else()
    pkg_check_modules(PC_REALSENSE2 QUIET librealsense2-dev)
endif()

set(REALSENSE2_DEFINITIONS ${PC_REALSENSE2_CFLAGS_OTHER})

#add a hint so that it can find it without the pkg-config
find_path(REALSENSE2_INCLUDE_DIR rs.hpp
          HINTS
          ${PC_REALSENSE2_INCLUDEDIR}
          ${PC_REALSENSE2_INCLUDE_DIRS}
          PATHS
            "${PROGRAM_FILES}/librealsense2/Include"
            /usr/include
            /usr/include/librealsense2
            /user/include
            /user/include/librealsense2
          PATH_SUFFIXES librealsense2
)

if(${CMAKE_CL_64})
    set(REALSENSE2_PATH_SUFFIXES lib64)
else()
    set(REALSENSE2_PATH_SUFFIXES lib)
endif()

#add a hint so that it can find it without the pkg-config
find_library(REALSENSE2_LIBRARY
             NAMES librealsense2.so
             HINTS
             ${PC_REALSENSE2_LIBDIR}
             ${PC_REALSENSE2_LIBRARY_DIRS}
             PATHS
               "${PROGRAM_FILES}/librealsense2"
               /usr/lib
               /usr/lib/x86_64-linux-gnu
               /user/lib
)

set(REALSENSE2_INCLUDE_DIRS ${REALSENSE2_INCLUDE_DIR})
set(REALSENSE2_LIBRARIES ${REALSENSE2_LIBRARY})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(librealsense2 DEFAULT_MSG
    REALSENSE2_LIBRARY REALSENSE2_INCLUDE_DIR)

mark_as_advanced(REALSENSE2_LIBRARY REALSENSE2_INCLUDE_DIR)

其中最值得關注的是find_path和find_library這兩個command。顧名思義,find_path是拿來找include path的,而find_library則是拿來找shared library location的。find_path主要格式如下(詳情見find_path):
find_path(
<VAR>
name | NAMES include_folder_or_file_name
[HINTS path1 path2 ...]
[PATHS path1 path2 ...]
[PATH_SUFFIXS suffix1 suffix2]
)
其中<VAR>即為XXX-INCLUDE_DIR,name可以是header name,比較特殊的是HINTS和PATHS,HINTS與PATHS最大差別是,HINTS會依照系統現有的變數去推測路徑,PATHS則是直接寫死路徑。PATH_SUFFIXS是路徑後綴,例如說rs.hpp實際上在Ubuntu 16.04的路徑是/usr/include/x86_64-linux-gnu/librealsense2/rs.hpp,而前面我們寫的路徑只有/usr/include/x86_64-linux-gnu,這時她會自動加上librealsense2這後綴到路徑中。PATH_SUFFIXS可以用來處理不同Linux distribution路徑放置的習慣問題(有些會像這個例子一樣把librealsense2的東西放入librealsense2中),若有多個cmake 會都try try看。
另一個類似的command是find_library(詳細在這find_library):
find_library(
<VAR>
name | NAMES libraries_name
[HINTS path1 path2 ...]
[PATHS path1 path2 ...]
[PATH_SUFFIXS suffix1 suffix2]
)
其中<VAR>即為XXX-LIBRARIES,其他欄位都和find_path一樣。而XXX-FOUND,則當find_path或是find_library都找不到東西實設為NOT-FOUND。

這個範例裡還有兩個好用東西值得一提,一是pkg_check_modules,這其實是pkg-config的再包裝,以前找opencv的library的時候很常用:
$ pkg-config opencv --libs
-lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco .......
cmake中的pkg-config功能也差不多,她會幫你找到所需的library放入指定的var中。如下:
 pkg_check_modules(PC_REALSENSE2 librealsense2-dev)
 這裡是用pkg_check_modules先依照package manager裡有的資訊尋找路徑,產生variable放入HINTS中。

另一個好用的東西是mark_as_advanced,這command會將該變數設為最高級別,當使用ccmake時不需要開啟advanced mode即可看到的變數。

CMake跟automake之類的比起來算是蠻方便的。

Friday, July 13, 2018

CMake Tricks: 一些小技巧

CMake Tricks: 一些小技巧

有常在編一些opensource的專案的應該都對CMake不陌生。這篇文章就整理些我在編使用CMake的專案時遇到的一些問題與解法。

追加Compiler flags

CMake裡面有一些變數是用來pass compiler flag給compiler,例如:CMAKE_CXX_FLAGS是用來給g++之類的C++ Compiler。這些變數當然是可以修改的。常見比較好的作法按依照該專案開發者定義的BUILD_TYPE來編,CMake裡面有一些常見的BUILD_TYPE,例如:Debug, Release, RelWithDebInfo ......等。可以透過在產生Makefile時下:
cmake -DCMAKE_BUILD_TYPE=value
來指定BUILD_TYPE,也可以在CMakeLists.txt中修改或是新增:
SET(CMAKE_CONFIGURATION_TYPES  "Release")
來給定。而BUILD_TYPE會使得該BUILD_TYPE中所定義的CMAKE_<LANG>_FLAGS_<BUILD_TYPE>被加入CMAKE_<LANG>_FLAGS中,例如:把build type設為Debug,會使得CMAKE_C_FLAGS_DEBUG被加入CMAKE_C_FLAGS中。這裡cmake官方文件寫得很清楚reference

若要自行追加flags也可以透過新增或是修改flags到CMAKE_<LANG>_FLAGS中。例如:
SET(GCC_COVERAGE_COMPILE_FLAGS "-g")
SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
我這裡的作法是新創一個變數GCC_COVERAGE_COMPILE_FLAGS,將其設為"-g",然後把她加入CMAKE_CXX_FLAGS中。

此外還有一個簡單有效的作法。由於CMAKE_C_FLAGS會依照環境變數CFLAGS初始化,所以只要修改CFLAGS這個環境變數就好。其他常見的對應如下:

  • CMAKE_C_FLAGS -> CFLAGS
  • CMAKE_CXX_FLAGS -> CXXFLAGS 
  • CMAKE_CUDA_FLAGS -> CUDAFLAGS
  • CMAKE_Fortran_FLAGS -> FFLAGS

而若是使用ccmake來產生Makefile,可以在視窗中輸入t開啟進階選項。直接在選單中修改即可。ex:

Option

下選項分為兩種,一是直接下在command line中,另一種則是用ccmake。
下在command line,只要用-D就好,ex:
cmake -DCMAKE_BUILD_TYPE=value
然而用這個很難知道,有什麼選項可以下,而且很麻煩,不過如果你build project是用script只能用這招。至於要知道有哪些選項可以透過:
cmake -L
得到所有選項以及當前選擇。
另外一種下option的方式是ccmake, 在Arch中安裝cmake套件,Ubuntu中安裝cmake-curses-gui即可,用法就是把所有cmake的指令改成ccmake。

當更新選項重新build時,會因為路徑下有CMakeCache.txt造成build成上一個版本的設定。可以把CMakeCache.txt刪除,或是透過make rebuild_cache重新建立CMakeCache.txt

CMake debug

如果要撰寫cmake最大問題是不知道cmake variable的值,經過運行後會變什麼。可以透過查看CMakeCache.txt或是下cmake -LAH來查看值。


其他連結:https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/Useful-Variables

Blogger Syntax highlight over https

Blogger Syntax highlight over https

由於現在blogger要求https,以往的常用的scripts:
http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js
會因為是http而造成瀏覽器報錯,而且載入的code通常會失敗。因此這裡提供一個新的解法。

改用以下cdn由cloudflare提供的。就可以讓你的code在https下漂漂亮亮的。
打開blogger->theme->編輯HTML,在<head></head>中新增以下code。

 

reference:
https://cdnjs.com/libraries/SyntaxHighlighter
http://3cschool.blogspot.com/2014/02/blogger-syntaxhighlighter.html

精選文章

使用Ardunio Atmega2560 連接 nRF24L01+

使用Ardunio Atmega2560 連接 nRF24L01+ 關於library 目前主流有 https://github.com/maniacbug/RF24 與 https://github.com/TMRh20/RF24 這兩個。 其中TMRh20大大做...