🗐 電装工芸日記 - 舞台照明機器の製作とか -

能登半島地震で被災された方々にお見舞い申し上げます。

or 管理画面へ

タグ「タイムコード」を含む投稿[52件](2ページ目)

Icon of admin
 LTC Player から LTC Generator を制御するモジュールを本格的に書き始めました。
 ハードウェアを作った3ヶ月前の自分が何を考えていたか整理しつつ、bytes と bytearray を用いてシリアル通信の再構築です。
 USB-Serial 変換の FT232RL には LTC Generator であるとマークを埋め込みたいのですが、FT Prog では書き換わっていても、Python で読むとシリアルナンバーくらいしか書き換えが反映しません。排他処理が出来ればいいのでコレでもいいのですが腑に落ちません。

#タイムコード #Python
Icon of admin
 先週末、LTC Generator の関数を書いてました。モード値とタイムコード値から送信のバイナリを起こす関数です。
 この作業で Python の変数の型である bytes と bytearray の違いようやくわかりました。
 突き詰めたらどちらもバイトデータの羅列ってのが第一条件なんですが、コマンドで数値を処理するなら bytearray にしといた方が楽で、デバイスが送受信で扱うのは最終的に bytes ってだけでした。
 とかく serial、socket を扱うなら bytes と bytearray がわかってないと不便。bytes にしなくても送信は出来るのですが文字コードの悪魔がちょっかいを出してくるので便利機能に頼るにしても自力で bytes まで持っていくつもりで書いた方がいいし、受信はどこまで行っても bytes なので避けて通れません。アセンブラに慣れきってしまった自分にとって「バイナリのデータが読めるとホッコリするよねぇ~」なんです。

#タイムコード #Python
Icon of admin
 ディナーショーの現場です。
 仕込めてしまえは空き時間多め。

 LTC の時間値を扱う関数を書き上げました。
・msec からフレーム数得る物
・フレーム数から LTC の時間値を得る物
・時間値をインクリメント(+1)する物
・時間値を減算する物
 以上4つです。

 上3つは当たり前でも減算が必要か?って思われるかもしれませんが、卓がLTCを再認識するのに0.5秒くらいかかることへの対策に使います。試したのは MAdot2 ですが、LTCを停止すると認識が落ちますのでLTCを再開してもすぐには動作しません。ファーストCUEが遅れることになるので困ります。ところが2-3フレームを折り返し繰り返せば認識を維持しつつ進行を止めることが出来るのでコノ状態を Pause 処理にしようと思うのです。故に、現在値に対する減算が必要なのです。
 具体的には再開の頭フレームのマイナス1フレームからマイナス3フレームを繰り返して待機状態とします。マイナス何フレームで繰り返すのが適切かは卓に寄って違う可能性がありますので今後検証したいと思います。

 この後は LTC Generator 本体のファームウェアの手直しです。制御コマンドを少し増やしたいかなと。

#タイムコード #Python
Icon of admin
 29.97fp-NDF の場合、単位時間あたりのフレーム数は 29.97fps で 勘定は 30fps の NDF と同じです。
 ・・・ってことが頭の中で混乱しました。
 29.97fps-NDF はタイムコードの時間勘定が増えるため値の進みが遅くなります。
 こういった「増えると減る」みたいな関係は挙動の理解がややこしい。

#タイムコード
Icon of admin
 次の2つの関数を作成しました。
・時間値をフレーム数に変換
・フレーム数からタイムコード値に変換(30・29.97・25・24fpsNDF、29.97fpsDFをサポート)
 29.97fpsでは±1フレームの誤差が出ますが、他のfpsの様にキリ良く計算出来ないからです。演出機器を動かすなら29.97fps以外を使った方がいいと思います。
 ドロップフレーム(DF)の処理はパズルでした。規則は単純ですが、計算式だけで解を得られない数の置き換えは思った以上に難儀します。
 この後は LTC Player から得られる時間値からタイムコード値を自動でカウントし続けるモジュールを作ります。すでに試作品があるのでそれを参考にします。ここでもDFが面倒な課題となります。

#タイムコード
Icon of admin
 LTC のフレーム値の計算で悩む。
 ノンドロップフレームなら簡単ですが、29.97fpsドロップフレームではそうもいきません。実時間とタイムコードの値が合うのは1時間ごと、つまり途中は実時間とズレるのです。タイムコードは映像のフレームに時間形式のナンバリングを与える手法であって実時間を表す物ではありませんので仕方ありません。ズレがあるとしてもフレームナンバーをゼロからカウントするのは何も問題ありませんが、不特定の時間値からカウントされる場合に漠然とした疑問があるワケです。

 困っていても仕方がないので条件を整理しましょう。
 10分単位で考えてみます。
 30fpsなら10分で18,000フレームです。29.97fpsドロップフレームは10分の間に18カウントを落としますので17,982フレームです。フレーム長の伸縮比1.001を掛けますと17,999.92となり、時間差は0.08フレームです。秒に直すと0.0026秒くらいの誤差です。そんなに大きな値ではありませんねぇ。見た目にわかる人は皆無ですからあんまり気にしなくてよくね?
 となると、基準点(時毎もしくは10分毎)からのフレーム数を出し、このフレーム数からタイムコード値を得ればいいんでないか?大げさな感じもしますが、時間値で計算すると奇妙な繰り下がりが発生して計算が面倒だからです。30fpsの24時間分のフレーム数は 2,592,000 ですから32bitの整数でも十分管理出来ます。時間からフレームの枚数目を得る関数とフレームの枚数目から時間を得る関数を作っておけばどうにでもなりそう。
 ここまでやれば、都度の誤差は人が感知出来ないレベルに収まると思います。

#タイムコード
Icon of admin
 昨日書いたpython-vlcが別なPCでも再生出来るか、mp3以外のフォーマットも再生出来るかチェックしました。
 もちろんVLCで再生する物は問題なく再生出来ますが、VLCのアプリで再生するよりも音の締まりと広がりが良いように聴こえる。。。
 何が違うんでしょう!?

 音源再生アプリ(LTC Player)には一般的な音源プレーヤーにはあまり無い機能を付けます。
1)音源毎に音量設定
2)再生開始点、終了点の設定
3)曲の終わりで止めるか曲続きか。曲続きなら曲間秒数も設定。
4)処理が許せば、指定秒数からの F.I/O も実装。可能ならクロスフェードも実装。
 ダンスイベントですと音源の音量がマチマチですし、前後の無音(白身)がやたら長い物があったりするからです。
 通常は事前に音量と白身を調整して現場に臨むのですが、あったら便利かなと思う機能です。
 あとは、先日も書きましたが、raspberryPi pico を使ってプログラムマブルキーボードを作って外部スイッチにします。

#タイムコード #Python
Icon of admin
 LTC Generator は卓に繋いで20時間以上正常に連続動作しています。PCとのやりとりの都合で手直しはありますが、基本的な機能はこれで完成とします。
 python-vlcでの音出しも方向性が見えましたので、あと必要な要素はPC上のソフトウェアです。
 Pythonのウィンドウマネージャーはtkinterが一番ベタな選択肢です。Python標準ですから安定性が期待出来ますし、WindowsでもMacOSでもLinuxでも同じソースで動きます。もっと書きやすくデザイン性に優れたウィンドウマネージャーもあるそうですが、何が違うのかよくわからないですし、基本過ぎるモノに慣れれば便利な物も使えるでしょうから、当面はtkinterを勉強してみます。つか、目に見えないところで動作するソフトウェアばかり書いてきたので画面作りは苦手です。

#タイムコード #Python
Icon of admin
 python-vlc で音源を流す試験をしました。
 単に再生するだけなら簡単。
 ちょっと難儀したのは再生終了を確定する処理。再生後自動的にリセットされませんので、再生が終了したことを確認して後処理をしないといけません。
 vlc.MediaPlayer.is_playing()は再生中かどうかを把握出来ますが、これだけでは再生が終了したフェーズかわかりません。オレフラグ(下記ではis_playing)を併用して再生前か再生後かを判別します。再生後ならstop()を実行します。きちんとstop()しないともう一度再生が出来ないpython-vlc。
 下記は再生終了を確定する試験として繰り返し再生するモノです。

# -*- coding: utf-8 -*-

import time
import vlc

def play() :
 # 音声ファイルを定義
 play_music = ( [ vlc.MediaPlayer() ] )
 try :
  play_music[0].set_mrl( 'C:/音源.mp3' )
 except :
  return -1
 # 再生ボリューム設定
 play_music[0].audio_set_volume( 60 )
 # フラグ定義
 is_playing = 0  # 再生実行済みフラグ

 # Main Loop
 while True :
  try :
   # 予備睡眠
   time.sleep( 0.0001 )  # Ctl-Cの反応を良くするのに少しsleepを入れるといい
   # 停止中
   if( play_music[0].is_playing() == 0 ) :
    # 未開始で停止中
    if( is_playing == 0 ) :
     play_music[0].play()
     while ( play_music[0].is_playing() == 0 ) : # 再生状態が確定するまで待つ
      time.sleep( 0.001 )
     play_music[0].set_time( 0 )
     is_playing = 1
    # 再生終了で停止中
    else :   # if( is_playing == 1 ) :
     play_music[0].stop()  # 再生終了を宣言してインスタンスをリセットする 主にこれをやりたいがための処理
     is_playing = 0
   # 再生中
   else :
    pass   # 再生中に行う処理は書いていないのでとりあえずpass

  # Ctl-Cで終了
  except KeyboardInterrupt :
   play_music[0].stop()
   break
 return 0

if __name__ == "__main__" :
 play()



 python-vlc便利過ぎ。

追記
 vlc.MediaPlayer.get_length()とvlc.MediaPlayer.get_time()を使って再生が最後まで行ったかチェックしました。
 何曲か試しましたが、概ねlengthの-0.1~-0.2秒で終了しています。vlc.MediaPlayer.get_time()は取得単位の1msecで厳密にカウントされているモノでも無さそうなので表示上の誤差かもしれません。トラック別で音繋がり場合は少し不安がありますが、音のお尻には1-2秒の余白があるのが一般的ですし、そこまで突き詰めるシステムではありませんのでいいかなと。
 画面作りをやって LTC Generator と合わせれば完成が見えてきそうです。
 ウィンドウマネージャーはPython標準のtkinterを使う勉強をしています。書式は違いますが、考え方はHTMLとCSSを使ったweb画面作りに酷似していますので、方言的に翻訳が出来れば何とかなりそうです。ただ、ボタン操作や画面の更新をオブジェクト指向のイベント処理(割り込み)で書くので少し面倒ですし、LTC Generator の制御やvlcの部分はバックグラウンドの常駐処理にしたいのでウィンドウ制御とは別スレッドとなり手間がかかるかも。

#Python #タイムコード
Icon of admin
 LTC Generator のLTC信号を卓(MA dot2)が認識しました。
 ただ、同じ値を送り続けても認識しません。LTCを入力してから認識するまで1秒弱かかるので、カウントを進めずに信号を認識し続ける方法が欲しいのです。
 試しに数フレームの繰り返しを組んでみたところ認識し、数フレームの繰り返しを一定回数行ってから抜ける様にしたところ期待する結果を得ました。
 最初のCUEポイントのマイナス数フレームの位置で2-3フレームの繰り返し待機をし、トリガが立ったらそれを抜ける考え方で良さそうです。
 ともかく、卓が認識したので一安心です。

#タイムコード

■当面の課題

桜のライトアップの季節です。花粉症の季節でもあります。
自分は平気ですが、花粉症の部下は死にそうな顔をしています。

編集

■全文検索:

複合検索窓に切り替える

■複合検索:

  • 投稿者名:
  • 投稿年月:
  • #タグ:
  • カテゴリ:
  • 出力順序:

■日付検索:

■カレンダー:

2023年8月
12345
6789101112
13141516171819
20212223242526
2728293031

■カテゴリ:

■最近の投稿:

最終更新日時:
2024年5月4日(土) 05時49分51秒