;

スポンサーサイト

0

    一定期間更新がないため広告を表示しています

    • 2019.10.15 Tuesday
    • -
    • -
    • -
    • by スポンサードリンク

    printf 関数で文字列を装飾する

    0
      C言語で標準出力に文字列を表示させる printf 関数。
      文字に色をつけたり下線を引くなどの装飾ができることを最近になって知った。

      たとえば、こんな具合。

      printf( "¥x1b[31mHello, World!¥n¥x1b[m" );

      いつもと違った世界(?) とのご対面だ。

      とはいえ、制御コードはとても覚えてられないし、毎回書くのもめんどくさい。
      なにより、書式を変えた後でデフォルトに戻すのを忘れると、以降の printf で設定が残ってしまい悲惨な結果になる。
      うまく使いたいなら、マクロで記述するのがベストだと思う。

      ○ソースコード


      #include <stdio.h>

      /* 印字用マクロ */
      #define PRINTF_COLOR_MAGENTA(...) printf("¥x1b[35m");¥
                                        printf(__VA_ARGS__);¥
                                        printf("¥x1b[39m")
      #define PRINTF_COLOR_CYAN(...) printf("¥x1b[36m");¥
                                     printf(__VA_ARGS__);¥
                                     printf("¥x1b[39m")
      #define PRINTF_UNDER_LINE(...) printf("¥x1b[4m");¥
                                     printf(__VA_ARGS__);¥
                                     printf("¥x1b[0m")

      int main(int argc, char **argv) {

          int i = 1;
          printf("%d: ふつうに印字¥n", i);
          i++;
          PRINTF_COLOR_MAGENTA("%d: マゼンタで印字¥n", i);
          i++;
          PRINTF_COLOR_CYAN("%d: シアンで印字¥n", i);
          i++;
          PRINTF_UNDER_LINE("%d: さらに下線もつけられるよ¥n", i);

          return 0;
      }


      ○結果



      自作ツールとかで NG を赤にするとか、汎用性は高いと思うので、知っておくと便利。

       

      プログラミング用フォント Ricty Diminished を使ってみる

      0
        Linux を使ったり、エディタでプログラムを書いたり、仕事と切り離せないのが文字のフォント
        それなのに、エディタには拘っても、フォントには拘る人ってあまり見ない。これは勿体ない。
        なぜなら、プログラミング向けのフォントというものがいくつか存在するからだ。

        しかし、プログラミング向けってどういうことだろうか?
        この一つとして知られている Ricty Diminished というフォントについて、導入手順とともにその素晴らしさを書き留めておきたい。

        ★ ★ ★ 

        1) 入れるべきフォントを決める

        一言でプログラミング用フォントといっても、いくつか種類がある。以下はその一例。
        1. Inconsolata
        2. Ricty / Ricty Diminished
        3. Circle M+

        調べたところ、2. は日本語がセットなので設定が楽ということで、Ricty に決定。
        疑問なのは、Ricty と Ricty Diminished の2種類の違い。
        前者は 生成スクリプトを使ってフォントを作るので少々手間なのに対して、後者はこれが不要ということなのでより楽ができる。
        というわけで、Ricty Diminished を選ぶ。


        2) コンピュータに導入

        http://save.sys.t.u-tokyo.ac.jp/~yusa/fonts/rictydiminished.html
        取得した.tar.gzを解凍し、.ttfをフォント格納場所にコピーする。
        Windows であれば、コントロールパネル -> フォント


        3) 使ってみる


        しばらく使ってみると、プログラミング向けといわれる所以が良く分かる。
         
        • 紛らわしい文字が明確に区別される
          • 数字の0と大文字のオー、ピリオドとカンマ、コロンとセミコロンなど
        • 全角スペースが明確にわかるように印字される
          • コンパイルエラーの原因が全角スペース…当初はよくありました(笑)
        • 半角2文字と全角1文字の横幅が同じ
          • 統一感があるのですごく見栄えがよい

        全角スペースでコンパイルエラーとかね、誰もが経験する道だと思うんですよ!
        それでプログラミングを嫌いになる人とか、いると思うんですよ!(学生の頃の私がそうだった...)
        そうした意味では、初心者から上級者まで、使用を強く勧めたいフォントだ。

        プロの料理人が食材毎に使う包丁を使い分けるように、プロのカメラマンが撮影対象に応じてカメラやレンズを使い分けるように、エンジニアも用途毎にツールや設定を上手く使い分けてこそ、プロというもの


        なーんて、偉そうに言える立場ではないけれど、「プログラミング用フォント使ってます」っていうのもちょっと格好いいじゃん。

         

        ALSAライブラリを使ったWAVデータの再生プログラム

        0
          Linxu で音を出すときに使うものとして有名な、ALSAというライブラリがある。
          カーネル空間のドライバと直接やりとりする必要がないので、手軽にデジタルオーディオの再生
          プログラムなどを実現することができる、というすぐれもの。

          今回初めて使ったライブラリなので、その環境準備とか、プログラムとかをメモ。

          環境構築 (Linux に ALSA ライブラリをインストール)

          1) 下記からファイルをダウンロード、解凍する
          http://alsa.cybermirror.org/lib/alsa-lib-1.0.27.2.tar.bz2

          2) 1) で解凍したディレクトリで、コンフィグとビルド
          $ ./configure
          $ make


          3) インストール
          $ sudo make install

          4) 確認
          $ ls /usr/include/alsa

          サンプルコード (sample.c)

          /* ALSA lib を使用して、WAVファイルを再生する */
          #include <stdio.h>
          #include <stdlib.h>
          #include <stdint.h>
          #include <alsa/asoundlib.h>
           
          /* PCMデフォルト設定 */
          #define DEF_CHANNEL         2
          #define DEF_FS              48000
          #define DEF_BITPERSAMPLE    16
          #define WAVE_FORMAT_PCM     1
          #define BUF_SAMPLES         1024
           
          /* ChunkID 定義 */
          const char ID_RIFF[4] = "RIFF";
          const char ID_WAVE[4] = "WAVE";
          const char ID_FMT[4]  = "fmt ";
          const char ID_DATA[4] = "data";
           
          /* PCM情報格納用構造体 */
          typedef struct {
              uint16_t      wFormatTag;         // format type  
              uint16_t      nChannels;          // number of channels (1:mono, 2:stereo)
              uint32_t      nSamplesPerSec;     // sample rate
              uint32_t      nAvgBytesPerSec;    // for buffer estimation
              uint16_t      nBlockAlign;        // block size of data
              uint16_t      wBitsPerSample;     // number of bits per sample of mono data
              uint16_t      cbSize;             // extra information
          } WAVEFORMATEX;
           
          /* CHUNK */
          typedef struct {
              char        ID[4];  // Chunk ID
              uint32_t    Size;   // Chunk size;
          } CHUNK;
           
          /* WAVE ファイルのヘッダ部分を解析、必要な情報を構造体に入れる
           *  ・fp は DATA の先頭位置にポイントされる
           *  ・戻り値は、成功時:データChunk のサイズ、失敗時:-1
           */
          static int readWavHeader(FILE *fp, WAVEFORMATEX *wf)
          {
              char  FormatTag[4];
              CHUNK Chunk;
              int ret = -1;
              int reSize;
               
              /* Read RIFF Chunk*/
              if((fread(&Chunk, sizeof(Chunk), 1, fp) != 1) ||
                 (strncmp(Chunk.ID, ID_RIFF, 4) != 0)) {
                  printf("file is not RIFF Format ¥n");
                  goto RET;
              }
           
              /* Read Wave */
              if((fread(FormatTag, 1, 4, fp) != 4) ||
                 (strncmp(FormatTag, ID_WAVE, 4) != 0)){
                  printf("file is not Wave file¥n");
                  goto RET;
              }
                       
              /* Read Sub Chunk (Expect FMT, DATA) */
              while(fread(&Chunk, sizeof(Chunk), 1, fp) == 1) {
                  if(strncmp(Chunk.ID, ID_FMT, 4) == 0) {
                      /* 小さい方に合せる(cbSize をケアするため) */
                      reSize = (sizeof(WAVEFORMATEX) < Chunk.Size) ? sizeof(WAVEFORMATEX) : Chunk.Size;
                      fread(wf, reSize, 1, fp);
                      if(wf->wFormatTag != WAVE_FORMAT_PCM) {
                          printf("Input file is not PCM¥n");
                          goto RET;
                      }
                  }
                  else if(strncmp(Chunk.ID, ID_DATA, 4) == 0) {
                      /* DATA Chunk を見つけたらそのサイズを返す */
                      ret = Chunk.Size;
                      break;
                  }
                  else {
                      /* 知らない Chunk は読み飛ばす */
                      fseek(fp, Chunk.Size, SEEK_CUR);
                      continue;
                  }
              };
               
          RET:
              return ret;
          }
           
          int main(int argc, char *argv[])
          {
              /* 出力デバイス */
              char *device = "default";
               /* ソフトSRC有効無効設定 */
              unsigned int soft_resample = 1;
               /* ALSAのバッファ時間[msec] */
              const static unsigned int latency = 50000;
               /* PCM 情報 */
              WAVEFORMATEX wf = { WAVE_FORMAT_PCM,   // PCM
                                  DEF_CHANNEL,
                                  DEF_FS,
                                  DEF_FS * DEF_CHANNEL * (DEF_BITPERSAMPLE/8),
                                  (DEF_BITPERSAMPLE/8) * DEF_CHANNEL,
                                  DEF_BITPERSAMPLE,
                                  0};
              /* 符号付き16bit */
              static snd_pcm_format_t format = SND_PCM_FORMAT_S16;
           
              int16_t *buffer = NULL;
              int dSize, reSize, ret, n;
              FILE *fp = NULL;
              snd_pcm_t *hndl = NULL;
               
           
              if(argc != 2) {
                  printf("no input file¥n");
              }
           
              /* WAVファイルを開く*/
              fp = fopen(argv[1], "rb");
              if (fp == NULL) {
                  printf("Open error:%s¥n", argv[1]);
                  goto End;
              }
           
              /* WAVのヘッダーを解析する */
              dSize = readWavHeader(fp, &wf);  
              if (dSize <= 0) {
                  goto End;
              }
               
              /* PCMフォーマットの確認と情報出力を行う */
              printf("format : PCM, nChannels = %d, SamplePerSec = %d, BitsPerSample = %d¥n",
                      wf.nChannels, wf.nSamplesPerSec, wf.wBitsPerSample);
           
              /* バッファの用意 */
              buffer = malloc(BUF_SAMPLES * wf.nBlockAlign);
              if(buffer == NULL) {
                  printf("malloc error¥n");
                  goto End;
              }
           
              /* 再生用PCMストリームを開く */
              ret = snd_pcm_open(&hndl, device, SND_PCM_STREAM_PLAYBACK, 0);
              if(ret != 0) {
                  printf( "Unable to open PCM¥n" );
                  goto End;
              }
               
              /* フォーマット、バッファサイズ等各種パラメータを設定する */
              ret = snd_pcm_set_params( hndl, format, SND_PCM_ACCESS_RW_INTERLEAVED, wf.nChannels,
                                        wf.nSamplesPerSec, soft_resample, latency);
              if(ret != 0) {
                  printf( "Unable to set format¥n" );
                  goto End;
              }
           
              for (n = 0; n < dSize; n += BUF_SAMPLES * wf.nBlockAlign) {
                  /* PCMの読み込み */
                  fread(buffer, wf.nBlockAlign, BUF_SAMPLES, fp);
           
                  /* PCMの書き込み */
                  reSize = (n < BUF_SAMPLES) ? n : BUF_SAMPLES;
                  ret = snd_pcm_writei(hndl, (const void*)buffer, reSize);
                  /* バッファアンダーラン等が発生してストリームが停止した時は回復を試みる */
                  if (ret < 0) {
                      if( snd_pcm_recover(hndl, ret, 0 ) < 0 ) {
                          printf( "Unable to recover Stream." );
                          goto End;
                      }
                  }
              }
           
              /* データ出力が終わったため、たまっているPCMを出力する。 */
              snd_pcm_drain(hndl);
           
          End:
               
              /* ストリームを閉じる */
              if (hndl != NULL) {
                  snd_pcm_close(hndl);
              }
               
              /* ファイルを閉じる */
              if (fp != NULL) {
                  fclose(fp);
              }
               
              /* メモリの解放 */
              if (buffer != NULL) {
                  free(buffer);
              }
               
              return 0;
          }


          コンパイル方法

          $ gcc -lasound -lm sample.c -o sample

          -> lasound が必須。使うAPI によっては浮動小数点が必要なので、-lm もつけたほうが無難。

          テスト

          第一引数に、再生したい WAV ファイルを入力
          $ ./sample 1000Hz_5sec_44100_mono.WAV


          -> 「ピーーーーー♪」
               準備したとおりの音(サンプリングレート44.1KHz, 1000 Hz のサイン波が 5秒間)が、再生された!

          最低限必要な API としては、

          • snd_pcm_open() でデバイスのハンドルを取得する
          • snd_pcm_set_params() でパラメータの設定をする
          • snd_pcm_writei() で PCM を書き込む
          • snd_pcm_close() でハンドルを返却する
          となる。API 仕様を読んで頑張って理解するしかない(どっか分かりやすいのないかな…)

          あとは、パラメータを設定するために、WAVE ファイルの構造の理解が必須というのもポイント。
          この辺はちょっと前に勉強したとこだったので、スムーズにできた。




           

          C言語オススメ書籍【その2】

          0
            2冊目。
            組込み現場の「C」プログラミング基礎からわかる徹底入門

             

            C言語オススメ書籍【その1】

            0
              情報系の学科を出ていながら、ポインタのポの時も理解していなかった大学時代。
              仕事でソフトウェア開発に携わるようになってから、必死こいて勉強をしてきてn年…

              基本は理解したし、以前と比べるとプログラムも書けるようになってきた。
              という訳で、C言語の学習において個人的にオススメな書籍を紹介していきたいと思います。

              まずは一冊目。
               
              評価:
              B.W. カーニハン,D.M. リッチー
              共立出版
              ¥ 3,024
              (1989-06-15)

              続きを読む >>

              | 1/1PAGES |

              PR

              calendar

              S M T W T F S
                 1234
              567891011
              12131415161718
              19202122232425
              262728293031 
              << July 2020 >>

              counter

              ブログパーツUL5

              books

              ひろの最近読んだ本

              selected entries

              categories

              archives

              recent comment

              links

              profile

              search this site.

              others

              mobile

              qrcode

              powered

              無料ブログ作成サービス JUGEM