openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
openFrameworksで太鼓の達人のようなプログラムを作りたいと思っています。
太鼓の画像を曲に合うように流せるようにはなりました。
ただそれは音が鳴らない状況で、どの曲を使うか知っているからこそその曲にあっていると理解できるようなものだと思うのですが、それでもうまくいっていると思っています。
でも、いざプログラムで音楽ファイル(.wav)を読み込んで再生させてみると、音と太鼓がずれています。
どのようにずれているのかというと、音に対して太鼓が遅れてしまっています。
最初のうちから遅れてしまうときもあれば、ある程度あっていると思っていたのに途中から遅れてくることもあります。
きっと曲を流すのに力を注いでいて、画面更新にまできちんと手が回っていないのかもしれません。
ただパソコンが重いだけかな?とも思うのですが、本当にそうなのでしょうか?
だとしたら、できるだけ他に何も起動していない状況で実行するしか解決法はないでしょうか?
OS:Windows7 HomePremium
openFrameworksのバージョン:007
参考にしている本:メディアアートのためのopenFrameworksプログラミング入門
プログラミング環境:Visual Studio 2010 Professional
フレームレート:60
使用する曲:ドレミの歌 (♪=120)
音楽ファイルの拡張子:wav
曲の再生と太鼓の画像を流すのは同時に行っています。
でも、太鼓の画像が流れる速さの調節のため、初め2秒は太鼓の画像は画面の外を移動しています。
(タイミング合わせて流れてくるよう、わざと画面の外から流す容姿しています。)
曲のほうは、それに合わせ初め2秒でテンポを取っています。
(♪チン チン チン ン(休み) のようにトライアングルの音をならしています。)
太鼓の画像を曲に合うように流せるようにはなりました。
ただそれは音が鳴らない状況で、どの曲を使うか知っているからこそその曲にあっていると理解できるようなものだと思うのですが、それでもうまくいっていると思っています。
でも、いざプログラムで音楽ファイル(.wav)を読み込んで再生させてみると、音と太鼓がずれています。
どのようにずれているのかというと、音に対して太鼓が遅れてしまっています。
最初のうちから遅れてしまうときもあれば、ある程度あっていると思っていたのに途中から遅れてくることもあります。
きっと曲を流すのに力を注いでいて、画面更新にまできちんと手が回っていないのかもしれません。
ただパソコンが重いだけかな?とも思うのですが、本当にそうなのでしょうか?
だとしたら、できるだけ他に何も起動していない状況で実行するしか解決法はないでしょうか?
OS:Windows7 HomePremium
openFrameworksのバージョン:007
参考にしている本:メディアアートのためのopenFrameworksプログラミング入門
プログラミング環境:Visual Studio 2010 Professional
フレームレート:60
使用する曲:ドレミの歌 (♪=120)
音楽ファイルの拡張子:wav
曲の再生と太鼓の画像を流すのは同時に行っています。
でも、太鼓の画像が流れる速さの調節のため、初め2秒は太鼓の画像は画面の外を移動しています。
(タイミング合わせて流れてくるよう、わざと画面の外から流す容姿しています。)
曲のほうは、それに合わせ初め2秒でテンポを取っています。
(♪チン チン チン ン(休み) のようにトライアングルの音をならしています。)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ここでopenFrameworksの話題が出たことがないので詳しい人は少ないかも知れません。
※ DirectXやDXライブラリに関しては詳しい人も多数。
どういう状況か説明だけよく分かりませんので、ソースコードの掲載や状況が分かる動画などをお願いします。
客観的にはCPU使用率の変化とか具体的な問題点も明らかに成っていると良いかと思います。
【補足】
openFrameworks見てみましたがJavaのprcessing的なフレームワークなんですね。
で、初心者にありがちなミスは毎フレーム読み込んだり毎フレーム無駄なことしている場合が多いです。
それと60fps出ているかも自己申告なので、ちゃんと計測されたものなのかも不明ですから客観的な情報がほしいです。
※ DirectXやDXライブラリに関しては詳しい人も多数。
どういう状況か説明だけよく分かりませんので、ソースコードの掲載や状況が分かる動画などをお願いします。
客観的にはCPU使用率の変化とか具体的な問題点も明らかに成っていると良いかと思います。
【補足】
openFrameworks見てみましたがJavaのprcessing的なフレームワークなんですね。
で、初心者にありがちなミスは毎フレーム読み込んだり毎フレーム無駄なことしている場合が多いです。
それと60fps出ているかも自己申告なので、ちゃんと計測されたものなのかも不明ですから客観的な情報がほしいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ソースを貼ってもらわないと何とも言えません。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
そもそもopenFrameworksの話題は出たことがないのですね。softya(ソフト屋) さんが書きました:ここでopenFrameworksの話題が出たことがないので詳しい人は少ないかも知れません。
※ DirectXやDXライブラリに関しては詳しい人も多数。
どういう状況か説明だけよく分かりませんので、ソースコードの掲載や状況が分かる動画などをお願いします。
客観的にはCPU使用率の変化とか具体的な問題点も明らかに成っていると良いかと思います。
C++使ったりするから―と思ったのですけど。
(一応事前にルール見に行きましたけど、質問してはいけない話題ってことはないですよね?)
動画は、私が持っているAGDRecでプレイ画面を録画しようとすると、録画を始めたとたん処理が遅くなるので・・・
録画設定もフレームレート60だからでしょうか?
同じ設定でMFCで作ったテトリスを録画したときはそんなことなかったのですが。
追記環境
プロセッサ:Intel(R) core(TM) 13CPU M 330 @ 2.13GHz 2.13GHz
実装メモリ(RAM):4.00GB(2.92GB 使用可能)
システムの種類:32ビット オペレーティング システム
ガジェットによるCPUの変化具合
プログラム起動前のCPU使用率:44%~53%
同時起動プログラム:IEタブ2つ(どちらもここの掲示板の異なる2ページを表示)・エクスプローラー(とあるフォルダを表示)・VS2010・Skype・コンピュータの管理・ガジェット3つ(スライドショー・CPU・RAM使用率・ニュース購読)・その他常駐ソフト(セキュリティーソフトなど)
プログラム起動直後:71%程度
プログラム起動後(スタート画面)数秒放っているときの使用率:45%~53%
ゲームスタート後(ただ流すだけでプレイ(キータッチ)せず):43%~63%
最終遅延:8秒ほど
ゲームスタート後(再生される曲に合わせてプレイしながら):44%~55%
最終遅延:9秒ほど
ゲームスタート後(流れてくる太鼓に合わせてプレイしながら):太鼓を見ながらメーターも見るというのが私には難しいため測定せず
最終遅延:11秒ほど
ゲームのプレイはどの回も最初から最後まで行っています。
プログラムソース(基本としているのは、openFrameworksに入っているemptyExample(ただ何も書かれていないウィンドウが表示されるだけのプログラム)です)
とりあえず、メインとなるtestApp.cppのみで。
#include "testApp.h"
//--------------------------------------------------------------
int x=640;
int speed=5;
int note[201]={45,15,45,15,30,30,60, //ドはドーナッツのド
45,15,15,15,15,15,120, //レはレモンのレ
45,15,45,15,30,30,60, //ミはみんなのミ
45,15,15,15,15,15,120, //ファはファイトのファ
45,15,15,15,15,15,120, //ソは青い空
45,15,15,15,15,15,120, //ラはラッパのラ
45,15,15,15,15,15,90, //シはしあわせよ
15,15,30,30,30,30,120, //さぁ歌いましょう
45,15,45,15,30,30,60, //どんなときにも
45,15,15,15,15,15,120, //列を組んで
45,15,45,15,30,30,60, //みんな楽しく
45,15,15,15,15,15,120, //ファイトをもって
45,15,15,15,15,15,120, //空を仰いで
45,15,15,15,15,15,120, //ラララララララ
45,15,15,15,15,15,90, //幸せの歌
15,15,30,30,30,30,60,60,30, //さぁ歌いましょう
30,30,30,30,30,30,30,30, //ドレミファソラシド
30,30,30,30,30,30,30, //ドシラソファミレ
30,30,60,30,30,60, //ドミミ ミソソ
30,30,60,30,30,60, //レファファ ラシシ
15,15,30,15,15,30,15,15,30,15,15,30, //ドミミ ミソソ レファファ ラシシ
15,15,30,15,15,30,15,15,30,15,15,30, //ドミミ ミソソ レファファ ラシシ
30,30,30,30,30,30,30,30,30,30,30,30,120, //ソドラファミドレ
30,30,30,30,30,30,30,30,30,30,30,30,135, //ソドラシドレド
15,15,15,15,15,15,15,60,60,120}; //ドレミファソラシド ソ ド
void testApp::setup()
{
ofSetLogLevel(OF_LOG_VERBOSE);
ofLog(OF_LOG_VERBOSE, "Start setup()");
// 画面の設定
ofSetFrameRate(60);
ofSetCircleResolution(128);
ofBackground(255, 255, 255);
ofSetWindowShape(480, 360);
ofEnableSmoothing();
//フォント読み込み
point_font.loadFont("vag.ttf", 18); //ソリューションパス\bin\data内にフォントを用意
game_font.loadFont("vag.ttf", 32);
//ゲーム画面の設定
menu=true; //メニューの表示
mouse_on=false; //マウスはボタンの外
//画面の混合の設定を加算合成にする
ofEnableAlphaBlending();
glEnable(GL_BLEND);
//画像データの読み込み
judge.loadImage("judge.png");
don.loadImage("don.png");
katsu.loadImage("katsu.png");
//曲の読み込み
strcpy(music,"dddkddddkdkdkddkkdkdkdkdkdkdddddddkkkkkkkdddddddkkkdddkddddkddddkdkdkddkkdkdkdkdkdkdddddddkkkkkkkdddddddkkkdddkdkkdkdkddddkdkdkkkdkkkdddkkkdddkkkdddkkkdddkkkdddkkkddddkkddkkddkkdddkkddkkddkkdddkdkdkdkd");
//各音の長さはグローバルで。
time=0; //0番目の太鼓から
wait=0; //次の太鼓を流すまでのカウント
sound.loadSound("Sound_of_doremi.wav");
sound.setLoop(false);
}
//--------------------------------------------------------------
void testApp::update()
{
if(menu==false && game==0){//ゲームの最中なら
if(wait==note[time]){ //次の太鼓を流してよくなるまで待ったら
time++; //次の太鼓を流す
if(time<202){
wait=0; //カウントし直し
if(music[time]=='d'){
drum[0].push_back(0);
}
else{
drum[0].push_back(1);
}
drum[1].push_back(640);
}
}
else{
wait++;
}
if(time<202 && drum[1].size()>0){ //終わりではなくて、1つ以上太鼓が画面にあるなら
for(int n=0;n<drum[1].size();n++){
drum[1][n]=drum[1][n]-speed; //太鼓を流す
}
if(drum[1][0]<0){
if(check==0){ //もし太鼓が素通りされていたら
point=point-50;
check=-2;
}
}
if(drum[1][0]<-40){ //画面から見えなくなったら
for(int n=1;n<drum[1].size();n++){
drum[0][n-1]=drum[0][n];
drum[1][n-1]=drum[1][n];
}
drum[0].pop_back();
drum[1].pop_back();
check=0;
}
}
}
}
void testApp::draw() //setupで決めたフラッシュレートに従って呼び出される
{
if(menu==true){ //メニューを表示する
ofSetHexColor(0x000000);
game_font.drawString("Expert of Drum",100,150);
if(mouse_on==true){
ofSetColor(0,0,0);
ofRect(198,177,60,25);
ofSetColor(255,255,255);
ofRect(199,178,58,23);
}
ofSetHexColor(0x000000);
point_font.drawString("Start",200,200);
}
else{
//譜面のバーを描画
ofSetColor(0,0,0);
ofRect(0,147,480,3); //上バー
ofRect(0,210,480,3); //下バー
//画像で使える色を設定
ofSetColor(255,255,255);//全色可
//判定枠の描画
judge.draw(40,160);
//譜面に合わせてドンやカツを表示
if(drum[0].size()>0){
for(int n=0;n<drum[0].size();n++){
if(drum[0][n]==0){
don.draw(drum[1][n],160);
}
else{
katsu.draw(drum[1][n],160);
}
}
}
//文字等の描画
ofSetHexColor(0x000000);
switch (check){
case -2:
point_font.drawString("Very Bad...",40,120);
break;
case -1:
point_font.drawString("Bad...",40,120);
break;
case 1:
point_font.drawString("Good!",40,120);
break;
case 2:
point_font.drawString("Very Good!",40,120);
break;
}
char points[20];
sprintf(points,"Point : %d",point);
point_font.drawString(points,440-point_font.getStringBoundingBox(points,0,0).width,120);
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key)
{
// キーが押された時の処理
if(menu==false && game==0){ //ゲームの最中であるなら
if(time>=14){
time=time;
}
if(drum[0].size()>0){
if(drum[1][0]>=0 && drum[1][0]<=100){
switch (key)
{
case 'd':
testApp::checker(0);
break;
case 'k':
testApp::checker(1);
break;
}
}
}
}
}
void testApp::exit()
{
ofLog(OF_LOG_VERBOSE, "End Application");
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void testApp::keyReleased(int key)
{
// キーがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y )
{
// マウスが動かされた時の処理
if((x>=198 && x<=258) && (y>=179 && y<=202)){
mouse_on=true;
}
else{
mouse_on=false;
}
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
// マウスがドラッグされた時の処理
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
// マウスボタンが押された時の処理
if(menu==true && (x>=198 && x<=258) && (y>=179 && y<=202)){
mouse_on=0;
game=0;
menu=false;
testApp::start();
}
else if(game!=0){
menu=true;
}
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
// マウスボタンがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{
// ウィンドウがリサイズされた時の処理
ofSetWindowShape(480, 360);
}
void testApp::start(){
//得点の初期化
point=0;
count_point=0;
count_total=0;
drum[0].push_back(0);
drum[1].push_back(640);
sound.play();
}
void testApp::checker(int push){
if(push==drum[0][0]){
if(drum[1][0]>15 && drum[1][0]<55){
point=point+100;
check=2;
}
else if(drum[1][0]>0 && drum[1][0]<80){
point=point+50;
check=1;
}
else if(drum[1][0]>-20 && drum[1][0]<100){
point=point;
check=-1;
}
}
else{
check=-1;
}
for(int n=1;n<drum[1].size();n++){
drum[0][n-1]=drum[0][n];
drum[1][n-1]=drum[1][n];
}
drum[0].pop_back();
drum[1].pop_back();
}
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
setupのところでofSetFrameRate(60)に設定しているので、設定ではフレームレートは60のはずです。softya(ソフト屋) さんが書きました:それと60fps出ているかも自己申告なので、ちゃんと計測されたものなのかも不明ですから客観的な情報がほしいです。
フレームレートを測定するためにソフトを持っていないので、今すぐには測定することができません・・・
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
質問してはいけないって事ではなくて知らないから答えられないかも知れないって事ですね。かなたん さんが書きました:そもそもopenFrameworksの話題は出たことがないのですね。
C++使ったりするから―と思ったのですけど。
(一応事前にルール見に行きましたけど、質問してはいけない話題ってことはないですよね?)
コードはこれから見させて頂きます。
パッと見のコードの印象はarduino/processingなので、私はarduino/processingで組んだ事が有るりますからたぶん解析できると思います。
時間経過から計算できるので、自分で計算してDraw中に表示するだけです。かなたん さんが書きました: setupのところでofSetFrameRate(60)に設定しているので、設定ではフレームレートは60のはずです。
フレームレートを測定するためにソフトを持っていないので、今すぐには測定することができません・・・
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
計算方法を調べて計算してみました。softya(ソフト屋) さんが書きました:質問してはいけないって事ではなくて知らないから答えられないかも知れないって事ですね。
以前にもDXライブラリの質問とかMFCの質問とか答えていただきましたが、openFrameworksの話題は出していいのだろうか?と勝手に思っていたりしたので。
別に、やはり話題にしてはいけないというわけではないんですね。
arduinoもprocessingも全然知らないのですが、openFrameworksってそういうのとも関係があるのですね。softya(ソフト屋) さんが書きました:パッと見のコードの印象はarduino/processingなので、私はarduino/processingで組んだ事が有るりますからたぶん解析できると思います。
OpenGLと関係があるっぽいことは関数を調べたりしていたときに思っていましたが。
softya(ソフト屋) さんが書きました:時間経過から計算できるので、自分で計算してDraw中に表示するだけです。
調べたときの状況:前回のような状況で特にキータッチなどのプレイをせず太鼓を流しただけ
計算方法の参考に使ったサイト
文字列 - 基本編25 - OpenGL de プログラミング - livedoor Wiki(ウィキ)
OpenFrameworks doc 日本語訳
計算に使ったコード
//グローバル
int GLframe = 0; //フレーム数
int GLtimenow = 0;//経過時間
int GLtimebase=0;//計測開始時間
//Draw関数内
GLframe++; //フレーム数を+1
GLtimenow = ofGetElapsedTimeMillis();//経過時間を取得
if (GLtimenow - GLtimebase > 1000) //1秒以上たったらfpsを出力
{
printf("fps:%f\n",GLframe*1000.0/(GLtimenow-GLtimebase));
GLtimebase = GLtimenow;//基準時間を設定
GLframe = 0;//フレーム数をリセット
}
こうなるのは、環境のせいでしょうか?
測定結果
(startより前はスタート画面のとき、start以下は、プレイ中のときです。 プレイの最後まで測定しました。)
OF: OF_VERBOSE: Start setup()
fps:0.991080
fps:55.944056
fps:60.098522
fps:59.523810
fps:61.083744
fps:60.157791
fps:60.098522
fps:57.596822
fps:57.142857
fps:55.172414
fps:56.862745
fps:58.648111
fps:59.760956
fps:56.943057
fps:57.255676
fps:59.701493
fps:59.405941
fps:62.562066
fps:59.523810
fps:62.686567
fps:61.083744
fps:60.336301
fps:59.940060
fps:61.691542
start
fps:62.314540
fps:59.230010
fps:62.438057
fps:56.157635
fps:60.217177
fps:59.642147
fps:57.711443
fps:59.642147
fps:59.642147
fps:62.562066
fps:57.711443
fps:50.000000
fps:50.000000
fps:50.000000
fps:49.950050
fps:50.000000
fps:50.000000
fps:58.764940
fps:60.157791
fps:60.817547
fps:62.438057
fps:57.654076
fps:62.500000
fps:57.086614
fps:50.000000
fps:50.645482
fps:57.255676
fps:56.435644
fps:62.314540
fps:60.939061
fps:61.325420
fps:62.130178
fps:59.171598
fps:60.098522
fps:59.347181
fps:59.880240
fps:57.768924
fps:62.500000
fps:57.482656
fps:57.086614
fps:62.500000
fps:59.523810
fps:55.172414
fps:62.500000
fps:59.405941
fps:56.974460
fps:54.945055
fps:60.157791
fps:60.276680
fps:50.000000
fps:49.950050
fps:50.000000
fps:59.582920
fps:62.438057
fps:55.390702
fps:62.500000
fps:61.264822
fps:60.217177
fps:60.039370
fps:50.000000
fps:50.000000
fps:50.000000
fps:52.947053
fps:57.142857
fps:53.571429
fps:52.371542
fps:57.142857
fps:56.157635
fps:57.768924
fps:62.438057
fps:58.823529
fps:62.376238
fps:62.376238
fps:54.133858
fps:62.500000
fps:58.764940
fps:60.336301
fps:60.157791
fps:58.882236
fps:60.217177
fps:51.792829
fps:50.000000
fps:50.000000
fps:50.000000
fps:50.000000
fps:52.527255
fps:60.756972
fps:58.070866
fps:50.000000
fps:49.950050
fps:55.063913
fps:60.336301
fps:54.835494
fps:57.312253
fps:60.217177
fps:55.281343
fps:60.098522
fps:58.941059
fps:60.878244
fps:58.882236
fps:51.536174
fps:62.500000
fps:61.083744
fps:59.940060
fps:60.696517
fps:59.523810
fps:60.756972
fps:53.892216
fps:60.636183
fps:59.230010
fps:60.336301
fps:60.575968
fps:57.711443
fps:59.582920
fps:54.294176
fps:60.575968
fps:59.880240
fps:61.446977
fps:62.500000
fps:51.231527
fps:52.947053
fps:62.500000
fps:59.464817
fps:50.000000
fps:50.000000
OF: OF_VERBOSE: End Application
続行するには何かキーを押してください . . .
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
60fpsを保てないのはハードウェアが原因だと思います。
スペックとして書かれていないビデオチップ側の性能ではないでしょうか?
ソースコード見てみましたが、updateの中の処理も60fpsで動作している前提が崩れたらうまくいかない処理ですね。
waitカウントではなく経過時間(スタート時と今回の時間差)で現状のフレーム位置を計算すべきで、そうすれば音とのズレは防げるはずです。
スペックとして書かれていないビデオチップ側の性能ではないでしょうか?
ソースコード見てみましたが、updateの中の処理も60fpsで動作している前提が崩れたらうまくいかない処理ですね。
waitカウントではなく経過時間(スタート時と今回の時間差)で現状のフレーム位置を計算すべきで、そうすれば音とのズレは防げるはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
インテルのグラフィック/メディアコントロール・パネルにあるディスプレイの一般設定では、次のようになっていました。softya(ソフト屋) さんが書きました:60fpsを保てないのはハードウェアが原因だと思います。
スペックとして書かれていないビデオチップ側の性能ではないでしょうか?
解像度:1366x768
色深度:32ビット
リフレッシュレート:60Hz
ここら辺の設定が影響しているのでしょうか?
ここで質問するまで、実行してからの経過時間を調べるという考えがなかったので、あのようにwaitカウントで作っていたんです。softya(ソフト屋) さんが書きました:ソースコード見てみましたが、updateの中の処理も60fpsで動作している前提が崩れたらうまくいかない処理ですね。
waitカウントではなく経過時間(スタート時と今回の時間差)で現状のフレーム位置を計算すべきで、そうすれば音とのズレは防げるはずです。
でも、softya(ソフト屋)さんの言うように実行してからの経過時間を利用して作れば、音ずれは防げそうですね。
これから試してみようと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
リフレッシュレートは、GPU(ビデオチップ)がモニタ(液晶画面)を更新する周期でハードウェア的に固定周期です。かなたん さんが書きました:インテルのグラフィック/メディアコントロール・パネルにあるディスプレイの一般設定では、次のようになっていました。
解像度:1366x768
色深度:32ビット
リフレッシュレート:60Hz
ここら辺の設定が影響しているのでしょうか?
これに対してfpsはアプリが画面を更新する周期で上限下限の保証はありませんしfpsを保証するのはアプリの仕事です。
まぁ、リフレッシュレート以上に更新しても意味が無いですが下限として60fpsを維持する保証するものではないと言うことです。
モニタ(液晶画面)の更新とアプリの描画は非同期ですので、実時間で動く動画やサウンドに同期したい場合はアプリ側がちゃんと時間制御しないとズレまくる恐れが高いです。
それと1フレーム(1/60)の間にどれだけの描画が出来るかはパソコンの使用しているGPUチップやCPUの性能に左右されます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
サウンド再生は正確という前提も良くないと思いますけど。
ofSoundPlayer::getPositionやofSoundPlayer::getPositionMSを使ってサウンドの進行に合わせて処理を進めるべきかと。
ofSoundPlayer::getPositionやofSoundPlayer::getPositionMSを使ってサウンドの進行に合わせて処理を進めるべきかと。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
そっちがあるならシンクロはサウンドに合わせたほうがよさそうですね。ISLe さんが書きました:サウンド再生は正確という前提も良くないと思いますけど。
ofSoundPlayer::getPositionやofSoundPlayer::getPositionMSを使ってサウンドの進行に合わせて処理を進めるべきかと。
ISLeさん、ありがとうございます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
[softya(ソフト屋)さんの言うように実行してからの経過時間を頼りに作り直したところ、状況は改善しました。
それでも、2秒ほどの遅延が発生していました。
もしかしたらISLeさんの言うようにサウンドも気づいていなくても遅れているのかもしれません。
そこで、紹介してくれている関数を利用してみようと思いました。
ミリ秒単位で返してくれるであろうgetPositionMS関数は残念ながらofSoundPlayerには存在しない(class ofSoundPlayerにメンバーgetPositionMSはありません)(もしかしてISLeさんのとバージョンとか違う?)ようなので、きちんと存在したgetPosition関数を使うことにしました。
でも、getPosition関数って、開始0~終了1のfloatが返ってくるんですね。
これって1単位あたり1/曲の長さになると思うのですが、その単位って1ミリ秒ですか?
再生から760ミリ秒で0.006563が返ってきたので、曲の長さが1:57であることから0.006563/760*1000*117で1.0103...となるので、大体1ですからあってますよね?
でも、正確に1ではないので、やはりエクスプローラーで長さが1:57と書いてあっても、正確には1:56.~とミリ秒単位の値があるのだと思います。
そこで、読み込んだ曲の長さをミリ秒で返してくれる関数なんかがあればいいなと思ったのですが、残念ながらOpenFrameworks doc 日本語訳には載っていませんでした。
ということは、openFrameworksにはそのような関数は存在しないということですか?
だとしたら、音編集ソフトなどでミリ秒単位までの長さを調べたりするしか方法はありませんか?
ポジションを1ミリ秒あたりなどで考えられるようにしたいのですが。
それでも、2秒ほどの遅延が発生していました。
もしかしたらISLeさんの言うようにサウンドも気づいていなくても遅れているのかもしれません。
そこで、紹介してくれている関数を利用してみようと思いました。
ミリ秒単位で返してくれるであろうgetPositionMS関数は残念ながらofSoundPlayerには存在しない(class ofSoundPlayerにメンバーgetPositionMSはありません)(もしかしてISLeさんのとバージョンとか違う?)ようなので、きちんと存在したgetPosition関数を使うことにしました。
でも、getPosition関数って、開始0~終了1のfloatが返ってくるんですね。
これって1単位あたり1/曲の長さになると思うのですが、その単位って1ミリ秒ですか?
再生から760ミリ秒で0.006563が返ってきたので、曲の長さが1:57であることから0.006563/760*1000*117で1.0103...となるので、大体1ですからあってますよね?
でも、正確に1ではないので、やはりエクスプローラーで長さが1:57と書いてあっても、正確には1:56.~とミリ秒単位の値があるのだと思います。
そこで、読み込んだ曲の長さをミリ秒で返してくれる関数なんかがあればいいなと思ったのですが、残念ながらOpenFrameworks doc 日本語訳には載っていませんでした。
ということは、openFrameworksにはそのような関数は存在しないということですか?
だとしたら、音編集ソフトなどでミリ秒単位までの長さを調べたりするしか方法はありませんか?
ポジションを1ミリ秒あたりなどで考えられるようにしたいのですが。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
そういえばofSoundPlayerのメンバ変数にlengthと言うのがあるみたいですが、これはどんな値が格納されているんでしょうか?訂正、cppファイル見たら存在しませんでした。
もし曲の長さであれば位置を計算するのに使えると思いますが。
【補足】
波形編集ソフトなら秒以下の単位には対応しているはずですよ。
「窓の杜 - サウンド編集」
http://www.forest.impress.co.jp/lib/pic ... soundedit/
もし曲の長さであれば位置を計算するのに使えると思いますが。
【補足】
波形編集ソフトなら秒以下の単位には対応しているはずですよ。
「窓の杜 - サウンド編集」
http://www.forest.impress.co.jp/lib/pic ... soundedit/
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
一応Audacityという編集ソフトを持っているのですが、やはりプログラム組むときにそういうのを利用して調べておくしかなさそうですかね?
プログラム内で曲の長さを調べることはできなさそうですから・・・
プログラム内で曲の長さを調べることはできなさそうですから・・・
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
openFrameworksのソースコードでの実装を見る限り無いですね。かなたん さんが書きました:一応Audacityという編集ソフトを持っているのですが、やはりプログラム組むときにそういうのを利用して調べておくしかなさそうですかね?
プログラム内で曲の長さを調べることはできなさそうですから・・・
openFrameworksを改造すれば出来ますが、それではopenFrameworksを使っている意味がなくなるので。
使えるのは次の関数だけす。
void loadSound(string fileName, bool stream = false);
void unloadSound();
void play();
void stop();
void setVolume(float vol);
void setPan(float vol);
void setSpeed(float spd);
void setPaused(bool bP);
void setLoop(bool bLp);
void setMultiPlay(bool bMp);
void setPosition(float pct); // 0 = start, 1 = end;
float getPosition();
bool getIsPlaying();
float getSpeed();
float getPan();
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
プログラム内では調べられないとのことでAudacityで調べたところ、117.016100sだということがわかりました。
それを先ほどの式に代入すると、0.006563/760*1000*117.0161=1.0104...でした。
それでもきちんと1にはならないようです。
でも、とりあえずその長さを頼りに作り直してみようと思います。
それを先ほどの式に代入すると、0.006563/760*1000*117.0161=1.0104...でした。
それでもきちんと1にはならないようです。
でも、とりあえずその長さを頼りに作り直してみようと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
一部の値がfloatの精度のギリギリだと思いますので精度の高い計算は無理だと思います。
まぁ、doubleしても割り切れることはないと思いますのであるがまま受け入れて下さい。
ちなみにWindows7/Vista自身が描画で数フレーム遅延する仕様です。
「Windows7/Vista」
http://tunde.blog17.fc2.com/blog-entry-18.html
人間の脳は音と絵のズレが数フレームなら誤差補正するので気づかないと思いますが気づく人もいます。
まぁ、doubleしても割り切れることはないと思いますのであるがまま受け入れて下さい。
ちなみにWindows7/Vista自身が描画で数フレーム遅延する仕様です。
「Windows7/Vista」
http://tunde.blog17.fc2.com/blog-entry-18.html
人間の脳は音と絵のズレが数フレームなら誤差補正するので気づかないと思いますが気づく人もいます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
そうだったんですね。Windows7/Vista(Aero使用時)では「常に最大(3フレーム)の遅延状態」になる。
そこで、フレームレート頼りにしていたプログラムに対してもう一度チャレンジしてみることにしました。
サイトを参考にAeroを止めてみたり、グラフィックの設定にある3D基本設定をパフォーマンスにしてみたのですが、今度はfpsが50ぴったり止まり(最大50・下がると40いくつ)になってしまいました。
(さらに遅延するようになった?)
3D基本設定を反対の品質にしてみたところ、それでも変わりありませんでした。
3D基本設定は最初グラフィックと品質の間でしたが、その状況でAeroを止めて試したところ、それでも変わりませんでした。
そこで、3D基本設定は最初のままAeroは止めずに試してみたところ、それでも変わりませんでした。
実は以前試したときより同時起動しているプログラムが多いのですが、それにしても最大50"ぴったり"というのは・・・
ちなみに、実行させたのはソリューションフォルダ\binにあるExpert_of_Drum_debug.exeです。
そこで、Visual Studioから実行させてみたのですが、それでも変わりませんでした。
たくさん起動させすぎて、制限かけられたのでしょうか?
今試行錯誤中の再生ポジション同期で作っているもので試しても、変わりませんでした。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
fpsの計算の仕方の問題でちゃんとしたfpsが計測されていない可能性がありますね。
過去ログですが参考にして下さい。
「FPSがうまく制御できない • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?t=10547&p=84910
過去ログですが参考にして下さい。
「FPSがうまく制御できない • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?t=10547&p=84910
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
今作っているのとは違うプログラムで同じように計測してみました。
プログラム内容は、画面内を図形が跳ね返りながら移動するもので、跳ね返ると図形が変わるようになっています。
図形はプログラムに描かせた園・正三角形・四角形の3種類です。
スペースキーを押すと移動する図形の数が1づつ増えるのですが、計測の時はスペースキーを押したりせず、図形1つのみで行いました。
このプログラムは画像や音などの外部ファイルは使っていません。
計測に使用したコードは、前回と同じです。
以下がそのソースコード(testApp.cppのみ)です。
すると、同じようにフレームレートを60に設定しているはずが、なぜか32くらいしか出ませんでした。
実行結果
やはり、時間計測か何かで思ったように作動していないのでしょうか?
出力のタイミングは今のフレームで実行してから1000ミリ秒以上たったごとですし。 出力されるタイミングがちょうど1000ミリ秒のときもあれば、そうでないときもあるでしょうし。
だとしても、60のはずが32というのはおかしいですよね?
時間計測で誤差が生じても、そこまでfpsに影響を及ぼすとは思えませんから。
fpsの計算って、1000ミリ秒の間に表示されたフレーム数*1000/1000ミリ秒で求められるんですよね?
で、参考にしているものでは以下のようになっているから― たぶん計算式は間違えてないと思うのですが・・・
プログラム内容は、画面内を図形が跳ね返りながら移動するもので、跳ね返ると図形が変わるようになっています。
図形はプログラムに描かせた園・正三角形・四角形の3種類です。
スペースキーを押すと移動する図形の数が1づつ増えるのですが、計測の時はスペースキーを押したりせず、図形1つのみで行いました。
このプログラムは画像や音などの外部ファイルは使っていません。
計測に使用したコードは、前回と同じです。
以下がそのソースコード(testApp.cppのみ)です。
#include "testApp.h"
//--------------------------------------------------------------
int circleCount = 0;
vector <ofPoint*> speeds;
vector <ofPoint*> locs;
vector <ofColor*> colors;
int mode[100];
int GLframe = 0; //フレーム数
int GLtimenow = 0;//経過時間
int GLtimebase=0;//計測開始時間
void testApp::setup()
{
ofSetLogLevel(OF_LOG_VERBOSE);
ofLog(OF_LOG_VERBOSE, "Start setup()");
// 画面の設定
ofSetFrameRate(60);
ofSetCircleResolution(128);
ofBackground(255, 255, 255);
ofSetWindowShape(300, 300);
ofEnableSmoothing();
// 最初の円を一つ作る
speeds.push_back(new ofPoint(3, 4));
locs.push_back(new ofPoint(100, 100));
ofColor *color = new ofColor();
color->r = 0;
colors.push_back(color);
mode[0]=ofRandom(0, 3);
circleCount++;
}
//--------------------------------------------------------------
void testApp::update()
{
// 各円の座標の更新
for (int i = 0; i < circleCount; i++ ) {
ofPoint *loc = locs[i];
ofPoint *speed = speeds[i];
int locX = loc->x + speed->x;
int locY = loc->y + speed->y;
loc->set(locX, locY);
// 画面端まで来ていたら方向を反転させる
if (locX < 0 || locX > ofGetWidth()) {
speed->set(speed->x * -1, speed->y);
mode[i]=ofRandom(0, 3); //図形の形変更
}
if (locY < 0 || locY > ofGetHeight()) {
speed->set(speed->x, speed->y * -1);
mode[i]=ofRandom(0, 3); //図形の形変更
}
}
}
void testApp::draw()
{
// 各円の描画
for (int i = 0; i < circleCount; i++ ) {
ofPoint *pos = locs[i];
ofColor *color = colors[i];
ofSetColor(color->r, color->g, color->b);
switch(mode[i]){ //作成時に決めた形の図形表示
case 0:
ofCircle(pos->x, pos->y, 20);
break;
case 1:
ofRect(pos->x, pos->y, 40, 40);
break;
case 2:
ofTriangle(pos->x, pos->y-20,pos->x-20, pos->y+10,pos->x+20, pos->y+10);
break;
}
}
GLframe++; //フレーム数を+1
GLtimenow = ofGetElapsedTimeMillis();//経過時間を取得
if (GLtimenow - GLtimebase > 1000) //1秒以上たったらfpsを出力
{
printf("fps:%f\n",GLframe*1000.0/(GLtimenow-GLtimebase));
GLtimebase = GLtimenow;//基準時間を設定
GLframe = 0;//フレーム数をリセット
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key)
{
// キーが押された時の処理
switch (key)
{
// スペースキーが押された
case ' ':
// ランダムの座標と移動速度と色を新たな円として追加する
ofPoint *speed = new ofPoint(ofRandom(-5, 5), ofRandom(-5, 5));
ofPoint *loc = new ofPoint(ofRandom(0, 300), ofRandom(0, 300));
ofColor *color = new ofColor();
color->r = ofRandom(0, 255);
color->g = ofRandom(0, 255);
color->b = ofRandom(0, 255);
colors.push_back(color);
speeds.push_back(speed);
locs.push_back(loc);
mode[circleCount]=ofRandom(0, 3);
circleCount++;
break;
}
}
void testApp::exit()
{
ofLog(OF_LOG_VERBOSE, "End Application");
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void testApp::keyReleased(int key)
{
// キーがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y )
{
// マウスが動かされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
// マウスがドラッグされた時の処理
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
// マウスボタンが押された時の処理
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
// マウスボタンがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{
// ウィンドウがリサイズされた時の処理
}
実行結果
OF: OF_VERBOSE: Start setup()
fps:24.654832
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.512315
fps:32.512315
fps:32.512315
fps:32.512315
fps:32.512315
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
OF: OF_VERBOSE: End Application
続行するには何かキーを押してください . . .
出力のタイミングは今のフレームで実行してから1000ミリ秒以上たったごとですし。 出力されるタイミングがちょうど1000ミリ秒のときもあれば、そうでないときもあるでしょうし。
だとしても、60のはずが32というのはおかしいですよね?
時間計測で誤差が生じても、そこまでfpsに影響を及ぼすとは思えませんから。
fpsの計算って、1000ミリ秒の間に表示されたフレーム数*1000/1000ミリ秒で求められるんですよね?
で、参考にしているものでは以下のようになっているから― たぶん計算式は間違えてないと思うのですが・・・
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
この話すっかり市民権を得ているようですが、この仕様は、softya(ソフト屋) さんが書きました:ちなみにWindows7/Vista自身が描画で数フレーム遅延する仕様です。
「Windows7/Vista」
http://tunde.blog17.fc2.com/blog-entry-18.html
人間の脳は音と絵のズレが数フレームなら誤差補正するので気づかないと思いますが気づく人もいます。
「ディスプレイに表示されている画面(デバイス画面)が更新される以前にバックバッファをどんどんフリップすると最大3フレーム溜まる」
というものです。
これはプログラム側がリフレッシュレートのみに頼った手抜きをしている場合に発生します。
ベンチマーク系のソフトは最大描画性能を計るためにウェイトを入れないのでこの仕様に引っ掛かりますがそれは別の話だと思います。
プログラム側できちんと更新タイミングを計っているなら遅延は(フレームレートではなく)リフレッシュレートでの最大1フレーム以内になります。
さらにディスプレイのリフレッシュレートとフレームレートにズレがある場合でも余計なウェイトが不要になるメリットがあります。
常に遅延状態になると言うのは、モニタのリフレッシュレートによって実行速度が変わってしまうようなプログラムしか作れないと言っているのと同じですよ。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ところで、プログラム起動前のCPU使用率が44%~53%というのは異常な気がするのですが、ふつうそんなものなのでしょうか。
ウチではVisual C++ 2010 Express起動していても何もしていない状態では数%で10%を超えることはまず無いのですが。
ウチではVisual C++ 2010 Express起動していても何もしていない状態では数%で10%を超えることはまず無いのですが。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
CPUの話をしていた昨日は、そもそもパソコンの調子がおかしかったようです。ISLe さんが書きました:ところで、プログラム起動前のCPU使用率が44%~53%というのは異常な気がするのですが、ふつうそんなものなのでしょうか。
ウチではVisual C++ 2010 Express起動していても何もしていない状態では数%で10%を超えることはまず無いのですが。
昨日の夜とてもパソコンが重くなり、それでもそのまま再起動などせず使い続けてしまっていたのですが、とうとう今日の朝それまで充電し続けていたはずなのにもかかわらず、バッテリーで起動できなくなることがありました。
でも、あとで電源コードつないでしばらくすると電源が入るようになり、それでも「Windowsを起動しています」がいつもより遅いと思い、勝手に強制終了させてしまいました。
そのあと起動させてみると、私が今まで見たことのないメニュー画面(なんだったかな?)がでて、推奨と書いてある項目で起動するとチェックディスクが走ったりして、しばらくして見てみるといつものようこそ画面がでていました。
今ではいつも通り使えていて、たぶん問題はないです。
ちなみに、IEやVisual Studioなどいろいろと起動している今のCPUの使用率は、ガジェットによると5%程度(増えても1桁)のようです。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ただ画面に赤・緑・青の円を描画させるだけのプログラムでも、fpsは32程度でした。
testApp.cpp
fpsを計測した結果
変更していたディスプレイの設定などは元に戻しているのですが・・・
なぜこのように性能が落ちているように見えるのでしょうか?
testApp.cpp
#include "testApp.h"
//--------------------------------------------------------------
int circleCount = 0;
vector <ofPoint*> speeds;
vector <ofPoint*> locs;
vector <ofColor*> colors;
int mode[100];
int GLframe = 0; //フレーム数
int GLtimenow = 0;//経過時間
int GLtimebase=0;//計測開始時間
void testApp::setup()
{
ofSetLogLevel(OF_LOG_VERBOSE);
ofLog(OF_LOG_VERBOSE, "Start setup()");
// 画面の設定
ofSetFrameRate(60);
ofSetCircleResolution(128);
ofBackground(255, 255, 255);
ofSetWindowShape(300, 300);
ofEnableSmoothing();
// 最初の円を一つ作る
speeds.push_back(new ofPoint(3, 4));
locs.push_back(new ofPoint(100, 100));
ofColor *color = new ofColor();
color->r = 0;
colors.push_back(color);
mode[0]=ofRandom(0, 3);
circleCount++;
}
//--------------------------------------------------------------
void testApp::update()
{
// 各円の座標の更新
for (int i = 0; i < circleCount; i++ ) {
ofPoint *loc = locs[i];
ofPoint *speed = speeds[i];
int locX = loc->x + speed->x;
int locY = loc->y + speed->y;
loc->set(locX, locY);
// 画面端まで来ていたら方向を反転させる
if (locX < 0 || locX > ofGetWidth()) {
speed->set(speed->x * -1, speed->y);
mode[i]=ofRandom(0, 3); //図形の形変更
}
if (locY < 0 || locY > ofGetHeight()) {
speed->set(speed->x, speed->y * -1);
mode[i]=ofRandom(0, 3); //図形の形変更
}
}
}
void testApp::draw()
{
// 各円の描画
for (int i = 0; i < circleCount; i++ ) {
ofPoint *pos = locs[i];
ofColor *color = colors[i];
ofSetColor(color->r, color->g, color->b);
switch(mode[i]){ //作成時に決めた形の図形表示
case 0:
ofCircle(pos->x, pos->y, 20);
break;
case 1:
ofRect(pos->x, pos->y, 40, 40);
break;
case 2:
ofTriangle(pos->x, pos->y-20,pos->x-20, pos->y+10,pos->x+20, pos->y+10);
break;
}
}
GLframe++; //フレーム数を+1
GLtimenow = ofGetElapsedTimeMillis();//経過時間を取得
if (GLtimenow - GLtimebase >= 1000) //1秒以上たったらfpsを出力
{
printf("fps:%f\n",GLframe*1000.0/(GLtimenow-GLtimebase));
GLtimebase = GLtimenow;//基準時間を設定
GLframe = 0;//フレーム数をリセット
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key)
{
// キーが押された時の処理
switch (key)
{
// スペースキーが押された
case ' ':
// ランダムの座標と移動速度と色を新たな円として追加する
ofPoint *speed = new ofPoint(ofRandom(-5, 5), ofRandom(-5, 5));
ofPoint *loc = new ofPoint(ofRandom(0, 300), ofRandom(0, 300));
ofColor *color = new ofColor();
color->r = ofRandom(0, 255);
color->g = ofRandom(0, 255);
color->b = ofRandom(0, 255);
colors.push_back(color);
speeds.push_back(speed);
locs.push_back(loc);
mode[circleCount]=ofRandom(0, 3);
circleCount++;
break;
}
}
void testApp::exit()
{
ofLog(OF_LOG_VERBOSE, "End Application");
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void testApp::keyReleased(int key)
{
// キーがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y )
{
// マウスが動かされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
// マウスがドラッグされた時の処理
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
// マウスボタンが押された時の処理
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
// マウスボタンがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{
// ウィンドウがリサイズされた時の処理
}
OF: OF_VERBOSE: Start setup()
fps:29.126214
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.069971
fps:32.038835
fps:32.038835
fps:32.069971
fps:32.038835
OF: OF_VERBOSE: End Application
続行するには何かキーを押してください . . .
なぜこのように性能が落ちているように見えるのでしょうか?
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
張り付けるソースコードを間違えました・・・
#include "testApp.h"
//--------------------------------------------------------------
int GLframe = 0; //フレーム数
int GLtimenow = 0;//経過時間
int GLtimebase=0;//計測開始時間
void testApp::setup()
{
ofSetLogLevel(OF_LOG_VERBOSE);
ofLog(OF_LOG_VERBOSE, "Start setup()");
// 画面の設定
ofSetFrameRate(60);
ofSetCircleResolution(128);
ofBackground(0, 0, 0);
ofSetWindowShape(1000, 500);
ofEnableSmoothing();
//Rのセルを作成
cell_color[0].push_back(255);
cell_color[1].push_back(0);
cell_color[2].push_back(0);
cell_size.push_back((cell_color[0][0]+cell_color[1][0]+cell_color[2][0])/3);
cell_pos.push_back(new ofPoint(ofRandom(cell_size[0]/2,1000/3-cell_size[0]/2),ofRandom(cell_size[0]/2,500-cell_size[0]/2)));
cell_speed.push_back(new ofPoint(0,0));
//Gのセルを作成
cell_color[0].push_back(0);
cell_color[1].push_back(255);
cell_color[2].push_back(0);
cell_size.push_back((cell_color[0][1]+cell_color[1][1]+cell_color[2][1])/3);
cell_pos.push_back(new ofPoint(ofRandom(1000/3+cell_size[0]/2,1000/3*2-cell_size[0]/2),ofRandom(cell_size[0]/2,500-cell_size[0]/2)));
cell_speed.push_back(new ofPoint(0,0));
//Bのセルを作成
cell_color[0].push_back(0);
cell_color[1].push_back(0);
cell_color[2].push_back(255);
cell_size.push_back((cell_color[0][2]+cell_color[1][2]+cell_color[2][2])/3);
cell_pos.push_back(new ofPoint(ofRandom(1000/3*2+cell_size[0]/2,1000-cell_size[0]/2),ofRandom(cell_size[0]/2,500-cell_size[0]/2)));
cell_speed.push_back(new ofPoint(0,0));
}
//--------------------------------------------------------------
void testApp::update()
{
// 各円の座標の更新
// 画面端まで来ていたら方向を反転させる
}
void testApp::draw()
{
// 各円の描画
for(int n=0;n<cell_size.size();n++){
ofSetColor(cell_color[0][n],cell_color[1][n],cell_color[2][n]);
ofCircle(cell_pos[n]->x,cell_pos[n]->y,cell_size[n]/2);
}
GLframe++; //フレーム数を+1
GLtimenow = ofGetElapsedTimeMillis();//経過時間を取得
if (GLtimenow - GLtimebase >= 1000) //1秒以上たったらfpsを出力
{
printf("fps:%f\n",GLframe*1000.0/(GLtimenow-GLtimebase));
GLtimebase = GLtimenow;//基準時間を設定
GLframe = 0;//フレーム数をリセット
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key)
{
// キーが押された時の処理
}
void testApp::exit()
{
ofLog(OF_LOG_VERBOSE, "End Application");
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void testApp::keyReleased(int key)
{
// キーがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y )
{
// マウスが動かされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
// マウスがドラッグされた時の処理
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
// マウスボタンが押された時の処理
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
// マウスボタンがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{
// ウィンドウがリサイズされた時の処理
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
前にも書いた通り設定したofSetFrameRate(60);はプログラムの周期が60フレーム/秒を保証する物ではありません。
処理か描画が60フレーム/秒以内に終わらない場合は16.6666・・・msを超えてしまいます。
描画が軽いものでもオーバーする場合はopenFrameworksに問題があるか、OpenGL等のビデオドライバに問題があるか、パソコン自体に問題があるかですね。
windows7のエクスペリエンスインデックスの各値を教えて下さい。HDDの値は不要です。
処理か描画が60フレーム/秒以内に終わらない場合は16.6666・・・msを超えてしまいます。
描画が軽いものでもオーバーする場合はopenFrameworksに問題があるか、OpenGL等のビデオドライバに問題があるか、パソコン自体に問題があるかですね。
windows7のエクスペリエンスインデックスの各値を教えて下さい。HDDの値は不要です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
色の変わる円の方はcell_colorが未定義と言われてコンパイルできないのですが、図形が反射する方をコンパイルして動かしてみました。
50FPSで安定でした。
デスクトップコンポジション(Aero)を無効にしても変わりませんでした。
ソースコードを追ってみたところ、1フレームあたりのミリ秒を整数値で記録していました。
制御部分も何だかよく分からないコードですが、そもそもどうやっても正確に60FPSにはならない仕組みです。
フレームレートに依存しないように作るしかありませんね。
あとOpenGLを使っているのでAeroの描画遅延フレーム数は関係ないです。
描画遅延フレーム数はDirect3Dにしか有効ではありません。
50FPSで安定でした。
デスクトップコンポジション(Aero)を無効にしても変わりませんでした。
ソースコードを追ってみたところ、1フレームあたりのミリ秒を整数値で記録していました。
制御部分も何だかよく分からないコードですが、そもそもどうやっても正確に60FPSにはならない仕組みです。
フレームレートに依存しないように作るしかありませんね。
あとOpenGLを使っているのでAeroの描画遅延フレーム数は関係ないです。
描画遅延フレーム数はDirect3Dにしか有効ではありません。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
エクスペリエンスインデックスは以下の通りです。 (前回の更新 2012/5/31 21:48:17)softya(ソフト屋) さんが書きました:前にも書いた通り設定したofSetFrameRate(60);はプログラムの周期が60フレーム/秒を保証する物ではありません。
処理か描画が60フレーム/秒以内に終わらない場合は16.6666・・・msを超えてしまいます。
描画が軽いものでもオーバーする場合はopenFrameworksに問題があるか、OpenGL等のビデオドライバに問題があるか、パソコン自体に問題があるかですね。
windows7のエクスペリエンスインデックスの各値を教えて下さい。HDDの値は不要です。
(プライマリハードディスクは除く)
プロセッサ:1秒あたりの計算 5.9
メモリ(RAM):1秒あたりのメモリ操作 5.5
グラフィックス:Windows Aero のデスクトップ パフォーマンス 4.6
ゲーム用グラフィックス:3D ビジネスおよびゲーム グラフィックス パフォーマンス 5.3
色の変わる円・・・どのプログラムのことでしょうか?ISLe さんが書きました:色の変わる円の方はcell_colorが未定義と言われてコンパイルできないのですが、図形が反射する方をコンパイルして動かしてみました。
50FPSで安定でした。
デスクトップコンポジション(Aero)を無効にしても変わりませんでした。
ソースコードを追ってみたところ、1フレームあたりのミリ秒を整数値で記録していました。
制御部分も何だかよく分からないコードですが、そもそもどうやっても正確に60FPSにはならない仕組みです。
フレームレートに依存しないように作るしかありませんね。
あとOpenGLを使っているのでAeroの描画遅延フレーム数は関係ないです。
描画遅延フレーム数はDirect3Dにしか有効ではありません。
cell_colorが未定義とのことですから、3つの円が描画されるプログラムのことでしょうか?
だとしたら、cell_colorの定義はクラスで以下のようにしていました。 どうやっても正確に60fpsにならないというのは、何のためのofSetFrameRate(60);なのでしょうか?
OpenFrameworks doc 日本語訳を見てみると、ofSetFrameRateの説明は以下のように書いてありました。
ということは、私のパソコンに入っているディスプレーアダプターであるIntel(R) HD Graphicsなどが影響している・・・とか?void ofSetFrameRate(int targetRate);
フレーム率を指定する事によって、フレームレートをセットします.
垂直同期信号は画面更新をロックしてしまうので、
プログラムやビデオカードレベルによっては同期できない場合もあります.
メモ:このコードはofAppRunnerに実装されています.
毎回ぴったり60でなくても、そんなにばらついたり下がったりするものなのですか?
曲のポジション同期で組んでいるのは・・・十中八九私の考えミスなどでしょうが、太鼓がすごい速さで移動するんですよね・・・
//省略
new_time=sound.getPosition();
if((new_time-old_time)*1170161>=note[time]){ //次の太鼓を流してよくなるまで待ったら
time++; //次の太鼓を流す
if(time<202){
old_time=new_time;
if(music[time]=='d'){
drum[0].push_back(0);
}
else{
drum[0].push_back(1);
}
drum[1].push_back(640);
drum_time.push_back(new_time);
}
}
if(time<202 && drum[1].size()>0){ //終わりではなくて、1つ以上太鼓が画面にあるなら
for(int n=0;n<drum[1].size();n++){
drum[1][n]=40+(int)(0.3*(2000-(new_time-drum_time[n])*1170161)); //太鼓を流す
}
//省略
noteはms単位で記憶させているので、(new_time-old_time)*1170161のようにすればms単位になるはずだとおもったんですが・・・
この考えは違うのでしょうか・・・?
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
僕の方では、図形が反射する方?は60.2fぐらいでした。かなたん さんが書きました:
どうやっても正確に60fpsにならないというのは、何のためのofSetFrameRate(60);なのでしょうか?
OpenFrameworks doc 日本語訳を見てみると、ofSetFrameRateの説明は以下のように書いてありました。ということは、私のパソコンに入っているディスプレーアダプターであるIntel(R) HD Graphicsなどが影響している・・・とか?void ofSetFrameRate(int targetRate);
フレーム率を指定する事によって、フレームレートをセットします.
垂直同期信号は画面更新をロックしてしまうので、
プログラムやビデオカードレベルによっては同期できない場合もあります.
メモ:このコードはofAppRunnerに実装されています.
毎回ぴったり60でなくても、そんなにばらついたり下がったりするものなのですか?
曲のポジション同期で組んでいるのは・・・十中八九私の考えミスなどでしょうが、太鼓がすごい速さで移動するんですよね・・・soundの曲の長さが1170161msで、sound.getPosition()は1msごとに1/1170161ずつ増えていく・・・んですよね?//省略 new_time=sound.getPosition(); if((new_time-old_time)*1170161>=note[time]){ //次の太鼓を流してよくなるまで待ったら time++; //次の太鼓を流す if(time<202){ old_time=new_time; if(music[time]=='d'){ drum[0].push_back(0); } else{ drum[0].push_back(1); } drum[1].push_back(640); drum_time.push_back(new_time); } } if(time<202 && drum[1].size()>0){ //終わりではなくて、1つ以上太鼓が画面にあるなら for(int n=0;n<drum[1].size();n++){ drum[1][n]=40+(int)(0.3*(2000-(new_time-drum_time[n])*1170161)); //太鼓を流す } //省略
noteはms単位で記憶させているので、(new_time-old_time)*1170161のようにすればms単位になるはずだとおもったんですが・・・
この考えは違うのでしょうか・・・?
>どうやっても正確に60fpsにならないというのは、何のためのofSetFrameRate(60);なのでしょうか?
実際中身を見てみると(見る場所あってるかわからないけど)
void ofAppGlutWindow::setFrameRate(float targetRate){{
~略~
float durationOfFrame = 1.0f / (float)targetRate;
millisForFrame = (int)(1000.0f * durationOfFrame);
で、この「millisForFrame」を「glutIdleFunc」に登録した関数内で
Sleep(millisForFrame)してcallしているようです。
まぁ、16.6666...msなのが16msで呼ばれているから
「正確に60FPSにはならない」と言っているのではないかなと予想してみます。
後、色の変わる円の方は、色々と変数の宣言が足りないようなので
testApp.hに宣言しているのであれば、宜しければ見せていただけませんか?
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ばらついたり下がったりするのは性能によるものでしょうけど正確に60FPSにならないのは単にそういう実装だからです。かなたん さんが書きました:どうやっても正確に60fpsにならないというのは、何のためのofSetFrameRate(60);なのでしょうか?
(略)
ということは、私のパソコンに入っているディスプレーアダプターであるIntel(R) HD Graphicsなどが影響している・・・とか?
毎回ぴったり60でなくても、そんなにばらついたり下がったりするものなのですか?
こちらでofSetFrameRate(60);は50FPSで一定でした。
トントンさんが指摘された理由だけでは62FPSくらいになるはずなんですよね。
他にも理由がありそうです。
指定したフレームレートにならないのはそういうものだとあきらめるしかないですね。
特に海外では固定フレームレートが一般的ではないので期待できないと思います。
フレームレートを指定しないで経過時間で進行させるのが良いでしょう。
マルチプラットフォーム向けとしてはそれが適切です。
ちなみにFPS制御を解説しているサイトをけっこうたくさん見てきましたけど60FPSを正確に刻むコードを解説してるサイトは唯の一つも見たことがないです。
ソースコードを公開しているゲーム(あるいはそれに準ずる)ソフトの中にはきちんと実装されているものもありますけどそれもわたしの知る限りほんの僅かです。
なぜゼロから始まるのにold_timeを引く必要があるのでしょうか?かなたん さんが書きました:soundの曲の長さが1170161msで、sound.getPosition()は1msごとに1/1170161ずつ増えていく・・・んですよね?
noteはms単位で記憶させているので、(new_time-old_time)*1170161のようにすればms単位になるはずだとおもったんですが・・・
この考えは違うのでしょうか・・・?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
Intel(R) HD GraphicsのOpenGLドライバの性能次第と言ったところでしょうか。かなたん さんが書きました:ということは、私のパソコンに入っているディスプレーアダプターであるIntel(R) HD Graphicsなどが影響している・・・とか?
毎回ぴったり60でなくても、そんなにばらついたり下がったりするものなのですか?
WindowsメインであるDirectXドライバとはリソースを取り合うので性能低下は避けられないかも知れません。
あと主力であるDirectXドライバほどOpenGLドライバに開発に力を入れてるとは思えません。
言うなれば内蔵ビデオチップですのでボードのビデオカードの性能が優秀なわけではなく、OpenGL主体の高価なQuadroビデオカードほどOpenGLドライバに力を入れているはずもなくと言ったところですので60FPSが出る保証はまったくありません。
他にもopenFrameworksの問題とか色々考えられます。
試しにDXライブラリ(DirectX)のやつを動かしてみて60FPSが出るか試されてはどうでしょう?
「FPSがうまく制御できない • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?t=10547&p=84910
ISLeさんがFPS60で安定が出来るかをテストできるプログラムを添付してくれています。
これが安定していたらopenFrameworksかOpenGLが悪いって事で納得するしか無いです。
毎回の差分を取らず開始からの経過時間だけで管理したほうがシンプルになると思います。かなたん さんが書きました: soundの曲の長さが1170161msで、sound.getPosition()は1msごとに1/1170161ずつ増えていく・・・んですよね?
noteはms単位で記憶させているので、(new_time-old_time)*1170161のようにすればms単位になるはずだとおもったんですが・・・
この考えは違うのでしょうか・・・?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ごめんなさい・・・トントン さんが書きました:僕の方では、図形が反射する方?は60.2fぐらいでした。
>どうやっても正確に60fpsにならないというのは、何のためのofSetFrameRate(60);なのでしょうか?
実際中身を見てみると(見る場所あってるかわからないけど)となっていました。void ofAppGlutWindow::setFrameRate(float targetRate){{ ~略~ float durationOfFrame = 1.0f / (float)targetRate; millisForFrame = (int)(1000.0f * durationOfFrame);
で、この「millisForFrame」を「glutIdleFunc」に登録した関数内で
Sleep(millisForFrame)してcallしているようです。
私の知識では理解できず・・・
次のフレームはmillisForFrameだけSleepしたあと呼び出されるとかそういう話ですか?
確かに16msで呼び出していたら、それでは1フレームごとに0.6666...ms誤差が生じてしまうので、60フレームで40msの誤差が出ますね。トントン さんが書きました:まぁ、16.6666...msなのが16msで呼ばれているから
「正確に60FPSにはならない」と言っているのではないかなと予想してみます。
でも、そうなっているとすると62fpsくらいになっているはずですよね?
あの・・・色の変わる円ってどれのことか・・・トントン さんが書きました:後、色の変わる円の方は、色々と変数の宣言が足りないようなので
testApp.hに宣言しているのであれば、宜しければ見せていただけませんか?
とりあえず、今まで載せたプログラムのtestApp.hを載せることにします。
Drum of Expart(太鼓の達人もどき)
#ifndef _TEST_APP
#define _TEST_APP
#include "ofMain.h"
class testApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void exit();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void start();
void checker(int push);
ofTrueTypeFont point_font;
ofTrueTypeFont game_font;
int point;
int game;
bool menu;
bool mouse_on;
int count_point;
int count_total;
ofImage judge;
ofImage don;
ofImage katsu;
char music[201];
//int note[201]; グローバルで宣言
int time;
vector <int> drum[2];
vector <float> drum_time;
int check;
ofSoundPlayer sound;
ofSoundPlayer don_sound;
ofSoundPlayer katsu_sound;
float old_time;
float new_time;
};
#endif
#ifndef _TEST_APP
#define _TEST_APP
#include "ofMain.h"
class testApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void exit();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
};
#endif
#ifndef _TEST_APP
#define _TEST_APP
#include "ofMain.h"
class testApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void exit();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
vector <int> cell_color[3];
vector <int> cell_size;
vector <ofPoint*> cell_pos;
vector <ofPoint*> cell_speed;
};
#endif
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ISLe さんが書きました: 指定したフレームレートにならないのはそういうものだとあきらめるしかないですね。
特に海外では固定フレームレートが一般的ではないので期待できないと思います。
フレームレートを指定しないで経過時間で進行させるのが良いでしょう。
マルチプラットフォーム向けとしてはそれが適切です。
仕様ですか・・・softya(ソフト屋) さんが書きました:Intel(R) HD GraphicsのOpenGLドライバの性能次第と言ったところでしょうか。
WindowsメインであるDirectXドライバとはリソースを取り合うので性能低下は避けられないかも知れません。
あと主力であるDirectXドライバほどOpenGLドライバに開発に力を入れてるとは思えません。
言うなれば内蔵ビデオチップですのでボードのビデオカードの性能が優秀なわけではなく、OpenGL主体の高価なQuadroビデオカードほどOpenGLドライバに力を入れているはずもなくと言ったところですので60FPSが出る保証はまったくありません。
他にもopenFrameworksの問題とか色々考えられます。
できるだけスペックなどによる個体差が出ないようにした方がいいというのはわかりますが、私的にはフレームレートを頼れる方が作りやすかったです・・・
でも、今回いろいろとやっていてフレームレートは当てにならないので、きちんと経過時間などを利用して作れるようになりたいと思います。
noteに差分を記憶させるほうが、noteを見ていて見やすくていいんですよね。softya(ソフト屋) さんが書きました:試しにDXライブラリ(DirectX)のやつを動かしてみて60FPSが出るか試されてはどうでしょう?
これが安定していたらopenFrameworksかOpenGLが悪いって事で納得するしか無いです。
そのプログラムを試してみました。
最初のうちは59.いくつ~61.いくつくらいまでをふらふらしているようでしたが、しばらくすると60ちょうどで安定するようになりました。
ということは、openFrameworksかOpenGLが悪いってことですね・・・
そんなにフレームレートは当てにならないのに、なぜ設定したり利用したりするのですか?ISLe さんが書きました:ちなみにFPS制御を解説しているサイトをけっこうたくさん見てきましたけど60FPSを正確に刻むコードを解説してるサイトは唯の一つも見たことがないです。
ソースコードを公開しているゲーム(あるいはそれに準ずる)ソフトの中にはきちんと実装されているものもありますけどそれもわたしの知る限りほんの僅かです。
他に利用できるようなものはなかったのでしょうか・・・?
音のタイミングを記憶させているnoteは、それぞれの音の間隔をmsで記憶させているので、前の音を流してからどれくらいたったのかを取得するべくold_timeを引いているんです。ISLe さんが書きました:なぜゼロから始まるのにold_timeを引く必要があるのでしょうか?
この差分を利用した考えがよくないのかな・・・
softya(ソフト屋) さんが書きました:毎回の差分を取らず開始からの経過時間だけで管理したほうがシンプルになると思います。
差分でなくて開始からどれくらいで考えようかと思ったこともありましたが、次を流したりするのに前との差文が分かればnoteは差分のままでも行けると思ったので、noteをわかりやすくしておきたいと言うだけでやめにしていました。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
フレームレートが当てにならないわけではないです。かなたん さんが書きました:そんなにフレームレートは当てにならないのに、なぜ設定したり利用したりするのですか?
他に利用できるようなものはなかったのでしょうか・・・?
現にわたしの自作のフレームワークは正確にフレームレートを刻みます。
フレームレートをモニタのリフレッシュレートに依存していたり、タイミングの計算が正確ではないプログラムが巷にあふれているだけの話です。
それと同じようにopenFrameworksのフレームレート設定が当てにならないわけですね。
それがなぜなのかはopenFrameworksの中の人しか分からないことですが。
非力なハードウェアでは処理が間に合わないのでそもそもフレームレートを正確に維持できない(しようとするだけ無駄)という状況もあります。
固定フレームレートは特定のハードウェアだけを対象にする場合や十分に処理能力のあるハードウェアを対象にする場合でなければうまく機能しないのです。
そういう意味ではopenFrameworksが最初から正確なフレームレートを刻む気なんてないとしても仕方がないと思います。
old_timeは前のフレームで記録した再生位置ですよね。かなたん さんが書きました:音のタイミングを記憶させているnoteは、それぞれの音の間隔をmsで記憶させているので、前の音を流してからどれくらいたったのかを取得するべくold_timeを引いているんです。
この差分を利用した考えがよくないのかな・・・
noteがひとつ前からの差分であることとどうしてつながるのでしょうか。
old_timeはnoteの基準にはなりません。
過去のnoteを蓄積したものと再生位置を比較するしかないのでは?
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
openframeworkslibプロジェクトのプロパティで、プリプロセッサの定義にWIN32_HIGH_RES_TIMINGを追加するとtimeBeginPeriod(1);で初期化されて精度が上がるようになってました。
ただしofAppRunner.cppがコンパイルエラーになるので というコードを適当なところに追加してください。
openFrameworksはバージョン0071を使いました。
精度が上がってもどのみち正確ではないしフレームレートに依存しないようにしたほうが良いと思います。
コンパイルエラーになるのを放置しているくらいですからね。
ただしofAppRunner.cppがコンパイルエラーになるので というコードを適当なところに追加してください。
openFrameworksはバージョン0071を使いました。
精度が上がってもどのみち正確ではないしフレームレートに依存しないようにしたほうが良いと思います。
コンパイルエラーになるのを放置しているくらいですからね。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
確かにISLeさんのプログラムは正確でした。ISLe さんが書きました:フレームレートが当てにならないわけではないです。
現にわたしの自作のフレームワークは正確にフレームレートを刻みます。
私の言葉が足りずすいません・・・
openFrameworksはなんで60に設定しても50だったり32だったりしてしまうようなフレームレートを当てにしているんだろうなと。
MFCのタイマーはms単位ですよね。
今まで正確なタイミングを要求するようなものは作ったことないのですが、あれも遅延することあるのでしょうか?
そうですか・・・ISLe さんが書きました:フレームレートをモニタのリフレッシュレートに依存していたり、タイミングの計算が正確ではないプログラムが巷にあふれているだけの話です。
それと同じようにopenFrameworksのフレームレート設定が当てにならないわけですね。
それがなぜなのかはopenFrameworksの中の人しか分からないことですが。
非力なハードウェアでは処理が間に合わないのでそもそもフレームレートを正確に維持できない(しようとするだけ無駄)という状況もあります。
固定フレームレートは特定のハードウェアだけを対象にする場合や十分に処理能力のあるハードウェアを対象にする場合でなければうまく機能しないのです。
そういう意味ではopenFrameworksが最初から正確なフレームレートを刻む気なんてないとしても仕方がないと思います。
フレームレートにはスペック差があるにもかかわらず、無視してでも利用しているんですよね?
フレームレートって、そんなんでも利用したくなるものなのですか?
old_timeは太鼓を流し始めたら書き換えるようになっています。ISLe さんが書きました:old_timeは前のフレームで記録した再生位置ですよね。
noteがひとつ前からの差分であることとどうしてつながるのでしょうか。
old_timeはnoteの基準にはなりません。
過去のnoteを蓄積したものと再生位置を比較するしかないのでは?
決して、毎フレーム書き換えているわけではありません。
いや・・・私がそう書いているつもりでも、あのソースはそうはなっていないのでしょうか?
old_timeは新しく太鼓を流すごとにnew_timeに書き変えされるようにしているつもりで、そうしたら(new_time-old_time)*1170161>=note[time]が成り立つ頃にはまた新たな太鼓を流していいはずで、そのときにはまたold_timeはnew_timeに書き変えされるようにしているつもりなのですが・・・
note蓄積とnew_timeを比較する方が、誤差が少ないでしょうか?
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
せっかくですが、コンパイルエラーとかになるくらいなら、ますますフレームレートは頼らないので・・・ISLe さんが書きました:openframeworkslibプロジェクトのプロパティで、プリプロセッサの定義にWIN32_HIGH_RES_TIMINGを追加するとtimeBeginPeriod(1);で初期化されて精度が上がるようになってました。
ただしofAppRunner.cppがコンパイルエラーになるので というコードを適当なところに追加してください。
openFrameworksはバージョン0071を使いました。
精度が上がってもどのみち正確ではないしフレームレートに依存しないようにしたほうが良いと思います。
コンパイルエラーになるのを放置しているくらいですからね。
今のままでも、計算とか正しく行えば曲との同期がきちんと取れますよね?
うまくいっていないのは私が間違えているだけで・・・
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
openFrameworksで、もし正確にフレームレートを刻めないPCが有った場合はアサートすべきなんでしょうか?かなたん さんが書きました:確かにISLeさんのプログラムは正確でした。
私の言葉が足りずすいません・・・
openFrameworksはなんで60に設定しても50だったり32だったりしてしまうようなフレームレートを当てにしているんだろうなと。
MFCのタイマーはms単位ですよね。
今まで正確なタイミングを要求するようなものは作ったことないのですが、あれも遅延することあるのでしょうか?
openFrameworksの中の人の考え方次第ですが出来ないものは仕方ないとするのも考え方の一つです。
例えば割り切れて速度的に十分な余裕が有るフレームレート20とかにすれば、ほとんど正確になるのでは?
ofSetFrameRateの説明もこう書いてありますし
けっして保証するとか書いてないですよね。Attempts to set the frame rate to a given target by sleeping a certain amount per frame.
The results of this may vary based if vertical sync is enabled or disabled (either at the card level or via code), because this locks the drawing to intervals where the screen refreshes.
それとMFCと言うかWin32APIのタイマーは、かなり不正確です。
そもそもWM_TIMERメッセージで処理されますしマルチプロセス/マルチスレッド下で動いているのでms台の正確さは求めてはいけません。
これは非リアルタイムOSでマルチタスクOSであるWindowsの避けれない仕様です。
高速で快適なPCならそもそも気にならないでしょう。かなたん さんが書きました:そうですか・・・
フレームレートにはスペック差があるにもかかわらず、無視してでも利用しているんですよね?
フレームレートって、そんなんでも利用したくなるものなのですか?
低速なPCなら低FPSで安定しますので、そうやって利用します。
アニメーションのためにはできるだけ正確なフレームレートであったほうがスムーズに動きますし、フレームレートを使ったほうが管理が楽ですよね。
で、Windowsでゲームを作るなら安定した速度の出るDirectxを利用したほうが良いと思います。
DirectXのラッパーであるDXライブラリを使うというのは選択肢にはないのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
"実行時はフレームレートは当てにならないんだから、自分が設定したフレームレートを当てにプログラムを組むな。"softya(ソフト屋) さんが書きました:openFrameworksで、もし正確にフレームレートを刻めないPCが有った場合はアサートすべきなんでしょうか?
openFrameworksの中の人の考え方次第ですが出来ないものは仕方ないとするのも考え方の一つです。
例えば割り切れて速度的に十分な余裕が有るフレームレート20とかにすれば、ほとんど正確になるのでは?
というのはわかってますが、自分で設定した設定(今回のフレームレートに限らず)通りに動いてほしいと私は思うんですよ。
GIFアニメーションを作るときは、1コマごとに表示時間を設定して作りますよね。
といっても私は1秒何コマのものを作っているわけではないので確かめたことないのですが、たぶんその設定通りのはずですよね。
楽譜にはたいていテンポや拍子が書いてあって、演奏するときはそのテンポや拍子を元に速さを決めて演奏しますよね。
またテンポや拍子が分かれば、1拍子何秒などの情報を求めることもできますよね。
この情報って、誰が見ても基本変わらないですよね?
やはりSetTimerでセットした通り正確に動いているわけではないのですね。softya(ソフト屋) さんが書きました:それとMFCと言うかWin32APIのタイマーは、かなり不正確です。
そもそもWM_TIMERメッセージで処理されますしマルチプロセス/マルチスレッド下で動いているのでms台の正確さは求めてはいけません。
これは非リアルタイムOSでマルチタスクOSであるWindowsの避けれない仕様です。
タイマーってデフォルトだと誤差も当たり前なのですね・・・
アニメーションの時には、私は先ほど言った通り1秒あたり何コマでなく1コマ何秒表示させるのかで作っているので、フレームレートというより1コマ何秒の設定ができればいいんです。softya(ソフト屋) さんが書きました:高速で快適なPCならそもそも気にならないでしょう。
低速なPCなら低FPSで安定しますので、そうやって利用します。
アニメーションのためにはできるだけ正確なフレームレートであったほうがスムーズに動きますし、フレームレートを使ったほうが管理が楽ですよね。
いっそのこと、sleepなどでコマ間にwaitを入れるんでもいいくらい。
テレビなどのアニメーションではきちんと1秒何フレームで作っているでしょうから、確かにフレームレートを利用する方が楽なんでしょうけど。
最近のプログラミングの最終目的はkinectとWindowsでOpenNI・openFrameworksなどを使ってプログラミングしたいんです。softya(ソフト屋) さんが書きました:で、Windowsでゲームを作るなら安定した速度の出るDirectxを利用したほうが良いと思います。
DirectXのラッパーであるDXライブラリを使うというのは選択肢にはないのでしょうか?
知り合いのプログラミングの手伝いということで一緒にやっていて、週一しか予定が合わず、また私はkinectを持っていないというところから、一緒にやる日でないときは自分なりにkinectでなにがで作れそうかとか使用するプログラミング言語で何ができるのかを調べたり試したりしています。
openFrameworksに出会ったとき、openFrameworksはなにができるんだろう?と本を借りてみたところ、いろいろと面白そうなものができそうだなと思って気に入ったんです。
このプログラムをkinectと連動させるかどうかは、ポーズ認識などどの程度できるようになるかで変わりますが、とりあえずopenFrameworksでどういうことができるのかを試したりアイデアを実現させてみたいと思っていろいろとやっているところです。
というわけで、今回はDXライブラリなどを使うというのは選択肢にないんです。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
太鼓を流すのを曲のポジションに同期させている話ですが、
プログラムの考えは同じに曲の長さを115ピッタリにしてみたところ、素早く流れてしまうことはなくなったのですが、それでも少し遅れてしまっていました。
もしかして、前の時は桁を間違えた・・・かな?
そこで、ISLeさんが言っていたようにnoteの蓄積とnow_timeを比較するようにしてみたところ、私は誤差に気づかなくなりました。
毎回の差分に幾分か誤差があり、その誤差が誤差を読んで目立つようになっていたのだと思います。
これで対こと曲をそろえることができたので、「プログラムで曲を流すと、他の処理が遅くなる。」という問題は解決ということで。
以下が、うまく同期できたプログラムソース(testApp.cpp)です。
プログラムの考えは同じに曲の長さを115ピッタリにしてみたところ、素早く流れてしまうことはなくなったのですが、それでも少し遅れてしまっていました。
もしかして、前の時は桁を間違えた・・・かな?
そこで、ISLeさんが言っていたようにnoteの蓄積とnow_timeを比較するようにしてみたところ、私は誤差に気づかなくなりました。
毎回の差分に幾分か誤差があり、その誤差が誤差を読んで目立つようになっていたのだと思います。
これで対こと曲をそろえることができたので、「プログラムで曲を流すと、他の処理が遅くなる。」という問題は解決ということで。
以下が、うまく同期できたプログラムソース(testApp.cpp)です。
#include "testApp.h"
//--------------------------------------------------------------
int speed=5;
int note[201]={750,250,750,250,500,500,1000, //ドはドーナッツのド
750,250,250,250,250,250,2000, //レはレモンのレ
750,250,750,250,500,500,1000, //ミはみんなのミ
750,250,250,250,250,250,2000, //ファはファイトのファ
750,250,250,250,250,250,2000, //ソは青い空
750,250,250,250,250,250,2000, //ラはラッパのラ
750,250,250,250,250,250,1500, //シはしあわせよ
250,250,500,500,500,500,2000, //さぁ歌いましょう
750,250,750,250,500,500,1000, //どんなときにも
750,250,250,250,250,250,2000, //列を組んで
750,250,750,250,500,500,1000, //みんな楽しく
750,250,250,250,250,250,2000, //ファイトをもって
750,250,250,250,250,250,2000, //空を仰いで
750,250,250,250,250,250,2000, //ラララララララ
750,250,250,250,250,250,1500, //幸せの歌
250,250,500,500,500,500,1000,1000,500, //さぁ歌いましょう
500,500,500,500,500,500,500,500, //ドレミファソラシド
500,500,500,500,500,500,500, //ドシラソファミレ
500,500,1000,500,500,1000, //ドミミ ミソソ
500,500,1000,500,500,1000, //レファファ ラシシ
250,250,500,250,250,500,250,250,500,250,250,500, //ドミミ ミソソ レファファ ラシシ
250,250,500,250,250,500,250,250,500,250,250,500, //ドミミ ミソソ レファファ ラシシ
500,500,500,500,500,500,500,500,500,500,500,500,2000, //ソドラファミドレ
500,500,500,500,500,500,500,500,500,500,500,500,2250, //ソドラシドレド
250,250,250,250,250,250,250,1000,1000,1500}; //ドレミファソラシド ソ ド
void testApp::setup()
{
ofSetLogLevel(OF_LOG_VERBOSE);
ofLog(OF_LOG_VERBOSE, "Start setup()");
// 画面の設定
ofSetFrameRate(60);
ofSetCircleResolution(128);
ofBackground(255, 255, 255);
ofSetWindowShape(480, 360);
ofEnableSmoothing();
//フォント読み込み
point_font.loadFont("vag.ttf", 18); //ソリューションパス\bin\data内にフォントを用意
game_font.loadFont("vag.ttf", 32);
//ゲーム画面の設定
menu=true; //メニューの表示
mouse_on=false; //マウスはボタンの外
//画面の混合の設定を加算合成にする
ofEnableAlphaBlending();
glEnable(GL_BLEND);
//画像データの読み込み
judge.loadImage("judge.png");
don.loadImage("don.png");
katsu.loadImage("katsu.png");
//曲の読み込み
strcpy(music,"dddkddddkdkdkddkkdkdkdkdkdkdddddddkkkkkkkdddddddkkkdddkddddkddddkdkdkddkkdkdkdkdkdkdddddddkkkkkkkdddddddkkkdddkdkkdkdkddddkdkdkkkdkkkdddkkkdddkkkdddkkkdddkkkdddkkkddddkkddkkddkkdddkkddkkddkkdddkdkdkdkd");
//各音の長さはグローバルで
time=0; //0番目の太鼓から
sound.loadSound("Sound_of_doremi.wav");
sound.setLoop(false);
don_sound.loadSound("don.wav");
katsu_sound.loadSound("katsu.wav");
}
//--------------------------------------------------------------
void testApp::update()
{
if(menu==false && game==0){//ゲームの最中なら
new_time=sound.getPosition();
if(new_time*115000>=musicpos){ //次の太鼓を流してよくなるまで待ったら
time++; //次の太鼓を流す
if(time<202){
old_time=new_time;
if(music[time]=='d'){
drum[0].push_back(0);
}
else{
drum[0].push_back(1);
}
drum[1].push_back(640);
drum_time.push_back(new_time);
musicpos=musicpos+note[time];
}
}
if(drum[1].size()>0){ //終わりではなくて、1つ以上太鼓が画面にあるなら
for(int n=0;n<drum[1].size();n++){
drum[1][n]=40+(int)(0.3*(2000-(new_time-drum_time[n])*115000)); //太鼓を流す
}
if(drum[1][0]<0){
if(check==0){ //もし太鼓が素通りされていたら
point=point-50;
check=-2;
}
}
if(drum[1][0]<-40){ //画面から見えなくなったら
for(int n=1;n<drum[1].size();n++){
drum[0][n-1]=drum[0][n];
drum[1][n-1]=drum[1][n];
drum_time[n-1]=drum_time[n];
}
drum[0].pop_back();
drum[1].pop_back();
drum_time.pop_back();
check=0;
}
}
}
}
void testApp::draw() //setupで決めたフラッシュレートに従って呼び出される
{
if(menu==true){ //メニューを表示する
ofSetHexColor(0x000000);
game_font.drawString("Expert of Drum",100,150);
if(mouse_on==true){
ofSetColor(0,0,0);
ofRect(198,177,60,25);
ofSetColor(255,255,255);
ofRect(199,178,58,23);
}
ofSetHexColor(0x000000);
point_font.drawString("Start",200,200);
}
else{
//譜面のバーを描画
ofSetColor(0,0,0);
ofRect(0,147,480,3); //上バー
ofRect(0,210,480,3); //下バー
//画像で使える色を設定
ofSetColor(255,255,255);//全色可
//判定枠の描画
judge.draw(40,160);
//譜面に合わせてドンやカツを表示
if(drum[0].size()>0){
for(int n=0;n<drum[0].size();n++){
if(drum[0][n]==0){
don.draw(drum[1][n],160);
}
else{
katsu.draw(drum[1][n],160);
}
}
}
//文字等の描画
ofSetHexColor(0x000000);
switch (check){
case -2:
point_font.drawString("Very Bad...",40,120);
break;
case -1:
point_font.drawString("Bad...",40,120);
break;
case 1:
point_font.drawString("Good!",40,120);
break;
case 2:
point_font.drawString("Very Good!",40,120);
break;
}
char points[20];
sprintf(points,"Point : %d",point);
point_font.drawString(points,440-point_font.getStringBoundingBox(points,0,0).width,120);
}
}
//--------------------------------------------------------------
void testApp::keyPressed(int key)
{
// キーが押された時の処理
if(menu==false && game==0){ //ゲームの最中であるなら
if(time>=14){
time=time;
}
if(drum[0].size()>0){
switch (key)
{
case 'd':
don_sound.play();
if(drum[1][0]>=0 && drum[1][0]<=100){
testApp::checker(0);
}
break;
case 'k':
katsu_sound.play();
if(drum[1][0]>=0 && drum[1][0]<=100){
testApp::checker(1);
}
break;
}
}
}
}
void testApp::exit()
{
ofLog(OF_LOG_VERBOSE, "End Application");
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void testApp::keyReleased(int key)
{
// キーがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y )
{
// マウスが動かされた時の処理
if((x>=198 && x<=258) && (y>=179 && y<=202)){
mouse_on=true;
}
else{
mouse_on=false;
}
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button)
{
// マウスがドラッグされた時の処理
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button)
{
// マウスボタンが押された時の処理
if(menu==true && (x>=198 && x<=258) && (y>=179 && y<=202)){
mouse_on=0;
game=0;
menu=false;
testApp::start();
}
else if(game!=0){
menu=true;
}
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button)
{
// マウスボタンがリリースされた時の処理
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h)
{
// ウィンドウがリサイズされた時の処理
ofSetWindowShape(480, 360);
}
void testApp::start(){
//得点の初期化
point=0;
count_point=0;
count_total=0;
drum[0].push_back(0);
drum[1].push_back(640);
sound.play();
old_time=sound.getPosition();
drum_time.push_back(old_time);
musicpos=note[time];
}
void testApp::checker(int push){
if(push==drum[0][0]){
if(drum[1][0]>15 && drum[1][0]<55){
point=point+100;
check=2;
}
else if(drum[1][0]>0 && drum[1][0]<80){
point=point+50;
check=1;
}
else if(drum[1][0]>-20 && drum[1][0]<100){
point=point;
check=-1;
}
}
else{
check=-1;
}
for(int n=1;n<drum[1].size();n++){
drum[0][n-1]=drum[0][n];
drum[1][n-1]=drum[1][n];
drum_time[n-1]=drum_time[n];
}
drum[0].pop_back();
drum[1].pop_back();
drum_time.pop_back();
}
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
逆に高スペックなハードでは更新頻度を抑える効果があります。かなたん さんが書きました:フレームレートにはスペック差があるにもかかわらず、無視してでも利用しているんですよね?
フレームレートって、そんなんでも利用したくなるものなのですか?
何も変化がないのに描画だけをすごい速さで繰り返しても無駄ですからね。
バッテリーの消耗にも繋がりますし。
Windows98のころはタイマーの精度自体がどうしようもなかったですが、Windows2000になると1ミリ秒の精度は保証されるようになってたと思います。
SetTimerのイベントが遅れるのはイベントという仕組みを使っているから起こることであってタイマーの精度とは別の話です。
いまは確実に1ミリ秒以下の精度があるのでそれなりに工夫すれば正確なタイミングを取ることは可能です。
アニメにしても音楽にしても絶対的な速さではなくて相対的な速さです。
時間が一定の速さで流れていると考えるのは間違いです。
いまここにいる自分の感じる一秒が、外の世界から見たら1分の出来事かもしれません。
音楽に合わせて進めるというのは、例えば1分の音楽の演奏が始まってから終わるまでが1分間と考える、ということです。
実際の演奏に2分かかったとしてもそれを1分間として処理を進めるのです。
逆に考えればテンポを変えることができるようにするということになります。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
音楽再生とメインプログラム(のフレームレート)は時間軸が異なります。
なのですり合わせが必要です。
すべて再生した時点、つまりofSoundPlayer::getPositionが1を返す時点が再生時間(ミリ秒)とすることですり合わせができています。
なので実際にかかった再生時間にかかわらず音楽とタイミングが合うわけです。
公式サイトのリファレンスを見ただけなので機能するか分かりませんが、ofSoundPlayer::setSpeedで音楽の再生速度を変えるだけでゲームのテンポも合わせて変わるはずです。
試してみてください。
なのですり合わせが必要です。
すべて再生した時点、つまりofSoundPlayer::getPositionが1を返す時点が再生時間(ミリ秒)とすることですり合わせができています。
なので実際にかかった再生時間にかかわらず音楽とタイミングが合うわけです。
公式サイトのリファレンスを見ただけなので機能するか分かりませんが、ofSoundPlayer::setSpeedで音楽の再生速度を変えるだけでゲームのテンポも合わせて変わるはずです。
試してみてください。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
確かに、変化がないのに更新しているのは無駄ですよね。ISLe さんが書きました:逆に高スペックなハードでは更新頻度を抑える効果があります。
何も変化がないのに描画だけをすごい速さで繰り返しても無駄ですからね。
バッテリーの消耗にも繋がりますし。
でも、変化が激しい時とそうでないときとなんてたぶんプログラムにはわからないですよね?
激しいときでも抑えられてはプログラムの組み方によっては困るじゃないですか。
タイマーとしては精度が上がってきているのに、イベントで処理しているから精度以上に誤差があるのですね。ISLe さんが書きました:Windows98のころはタイマーの精度自体がどうしようもなかったですが、Windows2000になると1ミリ秒の精度は保証されるようになってたと思います。
SetTimerのイベントが遅れるのはイベントという仕組みを使っているから起こることであってタイマーの精度とは別の話です。
いまは確実に1ミリ秒以下の精度があるのでそれなりに工夫すれば正確なタイミングを取ることは可能です。
今の1分1秒も誰かが定めた物を頼りにしていますよね。ISLe さんが書きました:アニメにしても音楽にしても絶対的な速さではなくて相対的な速さです。
時間が一定の速さで流れていると考えるのは間違いです。
いまここにいる自分の感じる一秒が、外の世界から見たら1分の出来事かもしれません。
1年はぴったり365日ではなく、幾分か誤差があるので、4年に1度うるう年と言って1年が366日ある年があるんですよね。
その1年は、地球では地球が公転で太陽の周りを1周するのを基準にしているんですよね。
だから、よその星では1年が365日以上もっとある星もあったりするんですよね。
同期の頼りにしているもののテンポを変えたら、その同期全体でテンポが変わるはずですね。ISLe さんが書きました:音楽に合わせて進めるというのは、例えば1分の音楽の演奏が始まってから終わるまでが1分間と考える、ということです。
実際の演奏に2分かかったとしてもそれを1分間として処理を進めるのです。
逆に考えればテンポを変えることができるようにするということになります。
そしてきちんと同期していないものでは、誤差が発生したりするんですよね。
私はすべてミリ秒かなにかできちんと管理できるなら管理しやすいのにと思うんですけど、そううまくいかないから同期したいものの中でタイミングを自由に変えられるものを自由に変えずらいものに合わせて管理するんですよね。ISLe さんが書きました:音楽再生とメインプログラム(のフレームレート)は時間軸が異なります。
なのですり合わせが必要です。
すべて再生した時点、つまりofSoundPlayer::getPositionが1を返す時点が再生時間(ミリ秒)とすることですり合わせができています。
なので実際にかかった再生時間にかかわらず音楽とタイミングが合うわけです。
setSpeedで速度を2倍にしたり0.5倍にしたりしてみました。ISLe さんが書きました:公式サイトのリファレンスを見ただけなので機能するか分かりませんが、ofSoundPlayer::setSpeedで音楽の再生速度を変えるだけでゲームのテンポも合わせて変わるはずです。
試してみてください。
きちんと曲と同期できているようで、太鼓も曲に合わせて速度が変わることが確認できました。
でも、setSpeedって正確にはテンポを早くするというかピッチを上げたというか、1より大きくすると音が高くなり、1より小さくすると音が低くなるんですね。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
少なくともopenFrameworks 前提とするなら、openFrameworks の枠組みの中で動作するように書く必要があります。
あと起動時にテストして安定できるフレームレートを調べてから、そのPCで安定して表示できるフレームレートを選ぶというのも手です。
まぁ、音楽再生に合わせて太鼓の位置を調整してやれば相当変動がない限り問題のない表示ができるのでは無いかと思います。
※ 昔のゲーム機では30FPSとかザラだったので、30FPS程度でも問題なくプレイ出来ると思います。
【こっちも補足】
画一な性能のゲーム機と違いPCの場合はPC毎の性能差が激しいので可能な限り低い性能に合わせたほうが快適に遊べる人が増えることになります。
あえて不利なOpenGL系を選択するわけですから、より悪条件に合わせる必要が出てきます。
その知り合いの方とも相談して、低いスペックでの動作をどうするかを決められたほうが良いと思います。
ちなみに音楽の再生速度を変えるとピッチが変化します。これは周波数を上げたり下げたりしているのと同じだからです。
[補足] 音というのは波ですが、周波数は波の間隔で決まりますので再生速度を上げると波の間隔が詰まります。つまり周波数が上がります。
これはドップラー効果と呼ばれる救急車のサイレンが近づいてくると高くなり(車の速度分だけ波の間隔が狭まる)遠ざかると低くなる(車の速度分だけ波の間隔が広がる)のと同じ原理です。
周波数を変えないまま、再生速度だけ上がるのはピッチダウンを行いながら再生しなければいけないので実は高度な技術となります。
あと起動時にテストして安定できるフレームレートを調べてから、そのPCで安定して表示できるフレームレートを選ぶというのも手です。
まぁ、音楽再生に合わせて太鼓の位置を調整してやれば相当変動がない限り問題のない表示ができるのでは無いかと思います。
※ 昔のゲーム機では30FPSとかザラだったので、30FPS程度でも問題なくプレイ出来ると思います。
【こっちも補足】
画一な性能のゲーム機と違いPCの場合はPC毎の性能差が激しいので可能な限り低い性能に合わせたほうが快適に遊べる人が増えることになります。
あえて不利なOpenGL系を選択するわけですから、より悪条件に合わせる必要が出てきます。
その知り合いの方とも相談して、低いスペックでの動作をどうするかを決められたほうが良いと思います。
ちなみに音楽の再生速度を変えるとピッチが変化します。これは周波数を上げたり下げたりしているのと同じだからです。
[補足] 音というのは波ですが、周波数は波の間隔で決まりますので再生速度を上げると波の間隔が詰まります。つまり周波数が上がります。
これはドップラー効果と呼ばれる救急車のサイレンが近づいてくると高くなり(車の速度分だけ波の間隔が狭まる)遠ざかると低くなる(車の速度分だけ波の間隔が広がる)のと同じ原理です。
周波数を変えないまま、再生速度だけ上がるのはピッチダウンを行いながら再生しなければいけないので実は高度な技術となります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
なぜ激しいときに抑えられてしまうことになるのでしょう?かなたん さんが書きました:でも、変化が激しい時とそうでないときとなんてたぶんプログラムにはわからないですよね?
激しいときでも抑えられてはプログラムの組み方によっては困るじゃないですか。
フレームレートはそれ以上の更新速度にはしてほしくないという意味でもあります。
これ以上速くても無駄というのは自分で作ったものをテストプレイしていて分かりますよね(あるいは作る前から決めている)。
アクション性の低いパズルゲームあたりは30FPSでも十分過ぎます。
極端な話リフレッシュレートが1000Hzを超えると1フレームあたりの時間が1ミリ秒未満になってしまうので、ミリ秒精度を前提としたプログラムは動かなくなる可能性があります。
それは単位の基準の話ですね。かなたん さんが書きました:今の1分1秒も誰かが定めた物を頼りにしていますよね。
1年はぴったり365日ではなく、幾分か誤差があるので、4年に1度うるう年と言って1年が366日ある年があるんですよね。
その1年は、地球では地球が公転で太陽の周りを1周するのを基準にしているんですよね。
だから、よその星では1年が365日以上もっとある星もあったりするんですよね。
相対的速度の話ではありません。
そもそもこの世界にいるわたしたちにはこの世界の外から観測するすべがありませんからこの世界の時間軸上の時刻しか読み取ることができません。
最終的に全部ミリ秒で管理してうまくいったではないですか。かなたん さんが書きました:私はすべてミリ秒かなにかできちんと管理できるなら管理しやすいのにと思うんですけど、そううまくいかないから同期したいものの中でタイミングを自由に変えられるものを自由に変えずらいものに合わせて管理するんですよね。
うまくいかないのは1ミリ秒がどこでも同じ長さだと思っていることが理由です。
今回のプログラムで言うと、
- 再生されている音楽
- フレームレート管理下のメインルーチン
- かなたんさん
そして、かなたんさんは再生されている音楽やフレームレート管理下のメインルーチンの時間軸をその世界の外から観測しているのです。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
一緒にやっている人は芸術関係の人で、あまりプログラミングの知識を持ち合わせていないようです。
Flashやphp、htmlを使ったことはあるというのは聞いています。
kinectハックだけでなくC言語系やopen~はやったことないようです。
参考にしている「キネクトハッカーズマニュアル」にopenFrameworksを使ってのプログラミングが載っていて、それを使って作った例も載っていました。
その人は、その作った例までのことはできないだろうけど、openFrameworksを使えばいろいろなことができるようになると思っています。
というか、OpenNIとOpenCVでどういうのが作れるのだろう?状態です。
私も似たようなことを思っていたりします。
kinectハックはその人のパソコン(Windows Vistaのノート)を中心にやっています。
まだ実際に自分たちでプログラムを組んでみるところまで行っていない―環境準備等の段階で詰まっている(サンプルのビルドが通らない・・・)ので、具体的にどういうのを作りたいかは定まっていません。
openFrameworksをkinectハックで利用したサンプルのビルドで詰まっているので、このままうまくいかないのであれば、openFrameworksを使ったりするのをあきらめてOpenNIとOpenCVだけでやることにしてみましょうか?という流れになりつつもあります。
とりあえず、どの方法でkinectハックするにしてもそのVista上できちんと実行できれば問題ないです。
フレームレートを30に下げて計測してみたところ、fpsは、30.303030かそうでないかでした。
また、さらに半分の15にして計測してみると、その半分の15.151515かそうでないかでした。
下げれば下げるほど設定値に近づくというより、フレームレートを下げると誤差も同じ割合下がるというだけのようですね。
きちんとぴったりにさせるには、自分で手を加えないといけないと。
以前ビープ音を扱ってみたとき、音の変化と同様に音量の変化を感じた(プログラム内外で音量を変えたつもりはない)のですが、それもこういうのが関係しているのでしょうか?
Flashやphp、htmlを使ったことはあるというのは聞いています。
kinectハックだけでなくC言語系やopen~はやったことないようです。
参考にしている「キネクトハッカーズマニュアル」にopenFrameworksを使ってのプログラミングが載っていて、それを使って作った例も載っていました。
その人は、その作った例までのことはできないだろうけど、openFrameworksを使えばいろいろなことができるようになると思っています。
というか、OpenNIとOpenCVでどういうのが作れるのだろう?状態です。
私も似たようなことを思っていたりします。
kinectハックはその人のパソコン(Windows Vistaのノート)を中心にやっています。
まだ実際に自分たちでプログラムを組んでみるところまで行っていない―環境準備等の段階で詰まっている(サンプルのビルドが通らない・・・)ので、具体的にどういうのを作りたいかは定まっていません。
openFrameworksをkinectハックで利用したサンプルのビルドで詰まっているので、このままうまくいかないのであれば、openFrameworksを使ったりするのをあきらめてOpenNIとOpenCVだけでやることにしてみましょうか?という流れになりつつもあります。
とりあえず、どの方法でkinectハックするにしてもそのVista上できちんと実行できれば問題ないです。
フレームレートを30に下げて計測してみたところ、fpsは、30.303030かそうでないかでした。
OF: OF_VERBOSE: Start setup()
fps:21.868787
start
fps:30.303030
fps:30.273438
fps:30.155642
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.332681
fps:30.273438
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.214425
fps:30.332681
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.214425
fps:30.273438
fps:30.243902
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.332681
fps:30.243902
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.126336
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.332681
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.243902
fps:30.185005
fps:30.303030
fps:30.243902
fps:30.273438
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.243902
fps:30.303030
fps:30.332681
fps:30.273438
fps:30.303030
fps:30.243902
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.332681
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.332681
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.185005
fps:30.273438
fps:30.332681
fps:30.303030
fps:30.332681
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.273438
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.273438
fps:30.303030
fps:30.303030
fps:30.155642
fps:30.185005
fps:30.303030
fps:30.243902
fps:30.155642
fps:30.303030
OF: OF_VERBOSE: End Application
続行するには何かキーを押してください . . .
OF: OF_VERBOSE: Start setup()
fps:9.813543
fps:15.151515
fps:15.151515
start
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.108593
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.122873
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.165877
fps:15.137181
fps:15.122873
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.165877
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.122873
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.108593
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.165877
fps:15.151515
fps:15.165877
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.137181
fps:15.151515
fps:15.009381
fps:15.094340
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.165877
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.151515
fps:15.137181
fps:15.151515
fps:15.151515
fps:15.165877
OF: OF_VERBOSE: End Application
続行するには何かキーを押してください . . .
きちんとぴったりにさせるには、自分で手を加えないといけないと。
普通に再生速度を変えただけでは波が変わってしまうので、作曲ソフトのように音はそのままにテンポを変化させるというのは高度な動きなのですね。softya(ソフト屋) さんが書きました:ちなみに音楽の再生速度を変えるとピッチが変化します。これは周波数を上げたり下げたりしているのと同じだからです。
[補足] 音というのは波ですが、周波数は波の間隔で決まりますので再生速度を上げると波の間隔が詰まります。つまり周波数が上がります。
これはドップラー効果と呼ばれる救急車のサイレンが近づいてくると高くなり(車の速度分だけ波の間隔が狭まる)遠ざかると低くなる(車の速度分だけ波の間隔が広がる)のと同じ原理です。
周波数を変えないまま、再生速度だけ上がるのはピッチダウンを行いながら再生しなければいけないので実は高度な技術となります。
以前ビープ音を扱ってみたとき、音の変化と同様に音量の変化を感じた(プログラム内外で音量を変えたつもりはない)のですが、それもこういうのが関係しているのでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
openFrameworksの問題は、動作する環境次第で60fpsにするのが難しいこと(30fpsなら多分大丈夫)とopenFrameworks自体のフレームレート管理が適当なことでしょう。あとkinectが動作するまで持っていけるかは技術的なスキルとの兼ね合いです。そこをどう判断するかですね。
芸術関係で多く使われるprocessingと互換性が高いと思われるopenFrameworksですのでメインの人の使いこなせる確率が高そうではあります。他(DXライブラリ)でやってもkinectが簡単かは微妙ですが60fpsは出しやすくなると思います。
ビープ音の音量が変わるのはPCの出力エネルギーが一定で、スピーカーの周波数特性と耳の周波数特性が原因です。それぞれに音量が大きく出る&大きく聞こえる周波数があり一様ではありません。
まぁ、音に関しては学校の理科で習うより色々と複雑で音が波だとちゃんと理解していない人も沢山います。共振とか回折とかの話も一般的ではないでしょう。それほど身近ながら知られていないのが音です。
興味があったら、こんなのから読んでみてください。
「JSTバーチャル科学館|音の正体」
http://jvsc.jst.go.jp/find/sound/index.htm
「人間の耳の特性」
http://www.asahi-net.or.jp/~yl1h-nkmr/oto/tokusei.html
芸術関係で多く使われるprocessingと互換性が高いと思われるopenFrameworksですのでメインの人の使いこなせる確率が高そうではあります。他(DXライブラリ)でやってもkinectが簡単かは微妙ですが60fpsは出しやすくなると思います。
音楽ソフトのテンポは、また別の話でピッチシフトまで必要な場合はあんまりないんじゃないと思います(音の出る長さを変えるだけ)。サンプラーとかはピッチシフトするのが当たり前ですが。かなたん さんが書きました:普通に再生速度を変えただけでは波が変わってしまうので、作曲ソフトのように音はそのままにテンポを変化させるというのは高度な動きなのですね。
以前ビープ音を扱ってみたとき、音の変化と同様に音量の変化を感じた(プログラム内外で音量を変えたつもりはない)のですが、それもこういうのが関係しているのでしょうか?
ビープ音の音量が変わるのはPCの出力エネルギーが一定で、スピーカーの周波数特性と耳の周波数特性が原因です。それぞれに音量が大きく出る&大きく聞こえる周波数があり一様ではありません。
まぁ、音に関しては学校の理科で習うより色々と複雑で音が波だとちゃんと理解していない人も沢山います。共振とか回折とかの話も一般的ではないでしょう。それほど身近ながら知られていないのが音です。
興味があったら、こんなのから読んでみてください。
「JSTバーチャル科学館|音の正体」
http://jvsc.jst.go.jp/find/sound/index.htm
「人間の耳の特性」
http://www.asahi-net.or.jp/~yl1h-nkmr/oto/tokusei.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
フレームごとの変化量が少ないのなら、60と設定して60出なくてもきちんと対処できていればだいたい問題ないじゃないですか。ISLe さんが書きました: なぜ激しいときに抑えられてしまうことになるのでしょう?
フレームレートはそれ以上の更新速度にはしてほしくないという意味でもあります。
これ以上速くても無駄というのは自分で作ったものをテストプレイしていて分かりますよね(あるいは作る前から決めている)。
アクション性の低いパズルゲームあたりは30FPSでも十分過ぎます。
でも、フレームごとの変化量が多かった時、思ったような動きをしない可能性はありませんか?
GIFアニメを各コマ1/100sで作成したことがあります。
コマ上の円を8等分する間隔で円の中心から円周までの長さの線が移動するもので、8コマをループさせています。
各コマ1/100sとなると当然コマの切り替えが早く、時計回りに回るように作っていても反時計回りに回っているんじゃないか?と思えるように見えることもあります。
そんなGIFアニメをとある掲示板にアップしたのですが、掲示板の性能のためか何のためか、明らかに各コマ1/100sではなく、もっと遅くなってしまいました。
1コマの時間を延ばすべく線の動きなどを各コマ1/100sの何とか倍の時を考えて作り直そうかとも思いましたが、それではこのGIFアニメで見せたかったものがうまく表現できなくなるのではないか?と思い、投稿はそのままにあきらめました。
もし実際に作りなおしてみて私が思っているようにうまく表現できなかったとしたら、フレームレートが設定しているように出なくて困ったりするのも似たようなものですよね?
(今回の場合試していないのであくまで予想でしかないですけど。)
1フレームあたり1ミリ秒以下に設定すると、sleepがうまく働かないということですね?ISLe さんが書きました:極端な話リフレッシュレートが1000Hzを超えると1フレームあたりの時間が1ミリ秒未満になってしまうので、ミリ秒精度を前提としたプログラムは動かなくなる可能性があります。
わざと1001に設定してみたら、確かにそんなfpsは出ませんでした。
OF: OF_VERBOSE: Start setup()
fps:133.866134
fps:457.542458
fps:471.057884
start
fps:465.069860
fps:448.103792
fps:458.541459
fps:474.525475
fps:458.083832
fps:458.541459
fps:450.396825
fps:461.077844
fps:485.514486
OF: OF_VERBOSE: End Application
続行するには何かキーを押してください . . .
MFC(など)のSetTimerは1秒1000ミリ秒で設定できますよね。ISLe さんが書きました:最終的に全部ミリ秒で管理してうまくいったではないですか。
うまくいかないのは1ミリ秒がどこでも同じ長さだと思っていることが理由です。
今回のプログラムで言うと、が観測する1ミリ秒という時間がそれぞれ違うのです。
- 再生されている音楽
- フレームレート管理下のメインルーチン
- かなたんさん
そして、かなたんさんは再生されている音楽やフレームレート管理下のメインルーチンの時間軸をその世界の外から観測しているのです。
たとえば500と設定したとき、OnTimerでカウントさせていればそれは(だいたい?)500ミリ秒ごとにカウントされていることになりますよね。
1カウントはSetTimerで設定した値ですよね。
フレームレートを利用すると、フレームごとにカウントしたときはだいたい設定したフレームレートごとにカウントされていることになりますよね。
設定したあるいは実際に計測したフレームレートから1フレーム何ミリ秒であるかを計算することにより、1カウントが何ミリ秒かがわかりますよね。
MFCのようにミリ秒単位などで設定できれば、このような計算を必要とすることなく1カウントは設定した値ですよね。
getPositionは始まりを0、終わりを1としたfloat値を返しますよね。
これは、再生時間が同じでも曲の長さが違えば返ってくる値も違いますよね。
返ってきた値に曲の長さをかけてあげることにより、今何ミリ秒再生されたのかが分かりますよね。
もし返ってくる値がミリ秒単位なら、そんな計算いらないですよね。
それらは計算式さえかければミリ秒単位に変換させることができますが、私は最初からすべてミリ秒で扱えたら管理しやすいかなと。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
なるほど。おっしゃることは分かりました。かなたん さんが書きました:GIFアニメを各コマ1/100sで作成したことがあります。
コマ上の円を8等分する間隔で円の中心から円周までの長さの線が移動するもので、8コマをループさせています。
各コマ1/100sとなると当然コマの切り替えが早く、時計回りに回るように作っていても反時計回りに回っているんじゃないか?と思えるように見えることもあります。
テレビで自動車のタイヤが逆に回って見えたりスマホの動画で飛行機のプロペラが奇妙に変形したりするような状況ですね。
残念ながらわたしは商業プログラマなので再生環境を最優先に考えてあらかじめそういう状況にならないように作ります。
少なくともいまのところGIFアニメで1/100秒を再現できないことは容易に予測できるので作りはじめる前にもっと低いフレームレートを提案するでしょう。
残念ながらそうなりません。かなたん さんが書きました:MFC(など)のSetTimerは1秒1000ミリ秒で設定できますよね。
たとえば500と設定したとき、OnTimerでカウントさせていればそれは(だいたい?)500ミリ秒ごとにカウントされていることになりますよね。
1カウントはSetTimerで設定した値ですよね。
フレームレートを利用すると、フレームごとにカウントしたときはだいたい設定したフレームレートごとにカウントされていることになりますよね。
設定したあるいは実際に計測したフレームレートから1フレーム何ミリ秒であるかを計算することにより、1カウントが何ミリ秒かがわかりますよね。
MFCのようにミリ秒単位などで設定できれば、このような計算を必要とすることなく1カウントは設定した値ですよね。
タイマーの精度が低ければ500と設定しても500ミリ秒ちょうどにはカウントされませんしイベントが遅延すればさらにズレます。
サウンド再生のスレッドとメインプログラムのスレッドの実行速度が一致する保証もありません。
これはプログラムでフレームレートのタイミング計算の実装がマズくて誤差が蓄積していくのとは別の話です。
何度も言ってますけど指定した時間がいつでもどこでも実時間と一致すると考えてはいけません。
「再生時間が同じでも曲の長さが違えば返ってくる値も違いますよね」というのが意味不明です。かなたん さんが書きました:getPositionは始まりを0、終わりを1としたfloat値を返しますよね。
これは、再生時間が同じでも曲の長さが違えば返ってくる値も違いますよね。
返ってきた値に曲の長さをかけてあげることにより、今何ミリ秒再生されたのかが分かりますよね。
もし返ってくる値がミリ秒単位なら、そんな計算いらないですよね。
それらは計算式さえかければミリ秒単位に変換させることができますが、私は最初からすべてミリ秒で扱えたら管理しやすいかなと。
この文脈で再生時間と曲の長さって同じものではないのでしょうか?
openFrameworksの中の人はかなたんさんがいらないと思っている計算をするほうが便利だと思っているのでしょう。
音程を変えずに再生速度を変えることができなかったら同じ曲でもレベル毎にテンポの違う曲データを用意したりしますよね。
そうしたらはじめから相対位置で管理したほうがnoteテーブルが共通化できて(余分な計算もしなくて)便利だと思いますけど。
noteテーブルを音符を基準にした数値にすることもできますよ。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
適当でも何とかやっていけるから、適当なままなんでしょうね。softya(ソフト屋) さんが書きました:openFrameworksの問題は、動作する環境次第で60fpsにするのが難しいこと(30fpsなら多分大丈夫)とopenFrameworks自体のフレームレート管理が適当なことでしょう。
そこは自分たちでいろいろな方法を試してがんばっていこうと思っていますが、お互いの環境が違う(OSがVistaと7だったり、、VSが、2010でも無料版と有料版だったり、使えるOpenCVのバージョンが違ったり)こともあり、同じようにできるのだろうかと思っていたり。softya(ソフト屋) さんが書きました:あとkinectが動作するまで持っていけるかは技術的なスキルとの兼ね合いです。そこをどう判断するかですね。
processingというのもあるんですね。softya(ソフト屋) さんが書きました:芸術関係で多く使われるprocessingと互換性が高いと思われるopenFrameworksですのでメインの人の使いこなせる確率が高そうではあります。他(DXライブラリ)でやってもkinectが簡単かは微妙ですが60fpsは出しやすくなると思います。
もしうまくいかないならそういうのを利用することも提案してみようと思います。
サンプラーというのは聞いたことないのですが、確かに作曲ソフトでは各音を鳴らす長さを変えるだけでできますね。softya(ソフト屋) さんが書きました:音楽ソフトのテンポは、また別の話でピッチシフトまで必要な場合はあんまりないんじゃないと思います(音の出る長さを変えるだけ)。サンプラーとかはピッチシフトするのが当たり前ですが。
そしたらピッチシフトなどは必要ないですね。
スピーカーや耳によってビープ音の周波数によって音が大きく聞こえたり小さく聞こえたりするのですね。softya(ソフト屋) さんが書きました:ビープ音の音量が変わるのはPCの出力エネルギーが一定で、スピーカーの周波数特性と耳の周波数特性が原因です。それぞれに音量が大きく出る&大きく聞こえる周波数があり一様ではありません。
まぁ、音に関しては学校の理科で習うより色々と複雑で音が波だとちゃんと理解していない人も沢山います。共振とか回折とかの話も一般的ではないでしょう。それほど身近ながら知られていないのが音です。
本気で興味があるわけではないですが、紹介してくれたサイトも是非見てみようと思います。
私は少なくとも自分の環境できちんと動けばいいと思っていて、ちきんとは動かないときにどうしたらいいか悩む人です。ISLe さんが書きました:残念ながらわたしは商業プログラマなので再生環境を最優先に考えてあらかじめそういう状況にならないように作ります。
(この考えは商業などの一般公開向けには向いていないですね・・・)
そうだったんですね。ISLe さんが書きました:GIFアニメで1/100秒を再現できないことは容易に予測できる
少なくとも私が使用しているGIFアニメ作成用ソフト(giam)上では1/100秒で作れても、GIF形式で保存した時点でその精度はないと。
それでも設定できるのは・・・1/100秒はできなくても、ある程度大きいとピッタリにはならなくてもそれなりに合わせてくれるとか?
その精度は今のままではどうしてもできるわけがないので、どうにかしてでもフレームレートを下げてそれでも再現できるように工夫してみるしかないということなのですね。ISLe さんが書きました:作りはじめる前にもっと低いフレームレートを提案するでしょう。
今回のと同じプログラムを、以前Scratchで作っていたことがあります。ISLe さんが書きました:タイマーの精度が低ければ500と設定しても500ミリ秒ちょうどにはカウントされませんしイベントが遅延すればさらにズレます。
サウンド再生のスレッドとメインプログラムのスレッドの実行速度が一致する保証もありません。
これはプログラムでフレームレートのタイミング計算の実装がマズくて誤差が蓄積していくのとは別の話です。
何度も言ってますけど指定した時間がいつでもどこでも実時間と一致すると考えてはいけません。
ScratchにはMFCのようなタイマー関数やopenFrameworksのようなフレームレートなどはない(少なくともプログラミングしていて設定する部分がない)です。
それっぽいのであるといえば、起動してから今までどれくらいたったのかのタイマー(秒(小数点3桁まで)単位)くらい?
相対時間待って太鼓を流すタイミングになったら指定の位置に太鼓を配置し、そこから指定時間(秒(小数可 たぶん小数点3桁まで?)単位)内に指定位置まで移動するようにしています。
まだ未完成なこともあり、ちょっと流れてくる太鼓間違えてるなって言うのはあったりするのですが、今プレイしてみても今回のような遅延は発生していないように思います。
でも、キーイベントがうまくはいらない―ドレミの歌の8分音符連続部分などで太鼓もそのように流れてくるのですが、そのように対応させたキーを押してもとびとびにしか反応しなかったので、完成まではあきらめました。
openFrameworksではうまくいきませんでしたが、このようにScratchでは時間同期による音と太鼓の同期はうまくいっていました。
これは、たまたまというかなんというか、このプログラムではScratchで少なくとも私が気付くほどのの音の遅延や太鼓の遅延が発生しなかっただけでしょうか?
openFrameworksのようにすべてがScratchのようにはうまくいかないのでしょうが、私にとってはこのように時間で管理できる方がいいと思っています。
たとえば曲の長さ1分のAと曲の長さ2分のBがあったとき、もし再生位置は同じ30秒だとしても、getPositionはAでは1/2000、Bでは1/4000とことなる値を返しますよね?ISLe さんが書きました: 「再生時間が同じでも曲の長さが違えば返ってくる値も違いますよね」というのが意味不明です。
この文脈で再生時間と曲の長さって同じものではないのでしょうか?
そういうことを言いたくて書いたのですが・・・私の書き方がよくなくてうまく伝わらなかったようで。
もし曲のテンポに合わせて複数のデータを用意することにすると、曲の長さもそうですし同じ部分でも再生位置が変わってきますが、私はそのときは指定している時間に今のテンポ/元のテンポをかけてやればいいかなと。ISLe さんが書きました:openFrameworksの中の人はかなたんさんがいらないと思っている計算をするほうが便利だと思っているのでしょう。
音程を変えずに再生速度を変えることができなかったら同じ曲でもレベル毎にテンポの違う曲データを用意したりしますよね。
そうしたらはじめから相対位置で管理したほうがnoteテーブルが共通化できて(余分な計算もしなくて)便利だと思いますけど。
noteテーブルを音符を基準にした数値にすることもできますよ。
でも、openFrameworksの中の人などは、相対位置で管理できた方がnoteの蓄積そのままと比較できていいと思うんですね。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
ちなみにopenFrameworksの実装はC++ですがprocessingの実装はJavaです。
「Extended Language (API) \ Processing.org」
http://processing.org/reference/
processing本体にはサウンドがなくて別のライブラリを組み合わせます。
そういう意味では、openFrameworks用に自分で使いやすいライブラリを作ってやるというのは悪い方法ではないでしょう。
サウンドの再生位置ではなく、サウンドの再生時間を返す事ができるサウンドクラスを追加するのです。
そうすれば、お望みのサウンドの時間での管理になります。
もし絶対的にCPUの時間基準で管理したいのであればサウンドも画像もすべてそちらに同期させる必要が有りますが、それは全てプログラマーの管理で行う必要がありWindowsOSやAPIはそこまでの厳密な時間管理を行なっていませんので理解してくださいね。
時間管理を主体としたOSもあります。逆に言えばRTOSであると明言していないOSは時間管理に限界があると言うことです。
「リアルタイムオペレーティングシステム - Wikipedia」
http://ja.wikipedia.org/wiki/%E3%83%AA% ... 6%E3%83%A0
OpenCVはバージョン合わせるだけなのでさほどの問題とも思えません。
比率で言えば5コマの内3コマしか表示されません。つまり1/100の精度は必要なかったと思います。
「Extended Language (API) \ Processing.org」
http://processing.org/reference/
processing本体にはサウンドがなくて別のライブラリを組み合わせます。
そういう意味では、openFrameworks用に自分で使いやすいライブラリを作ってやるというのは悪い方法ではないでしょう。
サウンドの再生位置ではなく、サウンドの再生時間を返す事ができるサウンドクラスを追加するのです。
そうすれば、お望みのサウンドの時間での管理になります。
もし絶対的にCPUの時間基準で管理したいのであればサウンドも画像もすべてそちらに同期させる必要が有りますが、それは全てプログラマーの管理で行う必要がありWindowsOSやAPIはそこまでの厳密な時間管理を行なっていませんので理解してくださいね。
時間管理を主体としたOSもあります。逆に言えばRTOSであると明言していないOSは時間管理に限界があると言うことです。
「リアルタイムオペレーティングシステム - Wikipedia」
http://ja.wikipedia.org/wiki/%E3%83%AA% ... 6%E3%83%A0
もし出来るだけ多くの人に配布するなら最悪のパターンに合わせる必要性が出てくるでしょう。二人のPCでしか動かさないなら悪い方に合わせるだけでしょう。かなたん さんが書きました:そこは自分たちでいろいろな方法を試してがんばっていこうと思っていますが、お互いの環境が違う(OSがVistaと7だったり、、VSが、2010でも無料版と有料版だったり、使えるOpenCVのバージョンが違ったり)こともあり、同じようにできるのだろうかと思っていたり。
OpenCVはバージョン合わせるだけなのでさほどの問題とも思えません。
根本的な問題として、一般的な液晶モニタのリフレッシュレートが1/60なので1/100で作っても実際問題意味が無いのです。かなたん さんが書きました:そうだったんですね。
少なくとも私が使用しているGIFアニメ作成用ソフト(giam)上では1/100秒で作れても、GIF形式で保存した時点でその精度はないと。
それでも設定できるのは・・・1/100秒はできなくても、ある程度大きいとピッタリにはならなくてもそれなりに合わせてくれるとか?
比率で言えば5コマの内3コマしか表示されません。つまり1/100の精度は必要なかったと思います。
かなたんさんが相対位置で管理するライブラリを用意してあげれば解決する問題だと思います。かなたん さんが書きました:もし曲のテンポに合わせて複数のデータを用意することにすると、曲の長さもそうですし同じ部分でも再生位置が変わってきますが、私はそのときは指定している時間に今のテンポ/元のテンポをかけてやればいいかなと。
でも、openFrameworksの中の人などは、相対位置で管理できた方がnoteの蓄積そのままと比較できていいと思うんですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
それは相対時間ではなくて「起動してからの経過時間」という基準に合わせたからですよ。かなたん さんが書きました:ScratchにはMFCのようなタイマー関数やopenFrameworksのようなフレームレートなどはない(少なくともプログラミングしていて設定する部分がない)です。
それっぽいのであるといえば、起動してから今までどれくらいたったのかのタイマー(秒(小数点3桁まで)単位)くらい?
相対時間待って太鼓を流すタイミングになったら指定の位置に太鼓を配置し、そこから指定時間(秒(小数可 たぶん小数点3桁まで?)単位)内に指定位置まで移動するようにしています。
まだ未完成なこともあり、ちょっと流れてくる太鼓間違えてるなって言うのはあったりするのですが、今プレイしてみても今回のような遅延は発生していないように思います。
でも、キーイベントがうまくはいらない―ドレミの歌の8分音符連続部分などで太鼓もそのように流れてくるのですが、そのように対応させたキーを押してもとびとびにしか反応しなかったので、完成まではあきらめました。
openFrameworksではうまくいきませんでしたが、このようにScratchでは時間同期による音と太鼓の同期はうまくいっていました。
これは、たまたまというかなんというか、このプログラムではScratchで少なくとも私が気付くほどのの音の遅延や太鼓の遅延が発生しなかっただけでしょうか?
openFrameworksのようにすべてがScratchのようにはうまくいかないのでしょうが、私にとってはこのように時間で管理できる方がいいと思っています。
プログラムの相対速度が違ってもPCのタイマーが唯一絶対の時間軸となっているのです。
500ミリ秒経ったらまた500ミリ秒経つまで待つ、というふうにするとズレが蓄積していきますが、起動してからの経過時間は都度ズレても誤差を蓄積しません。
音楽再生は音楽再生の方で頑張ってPCのタイマーに合わせてくれます。
いまどきのPCなら音楽再生が遅延することはないと思います。保証はありませんが。
またPCのタイマー自体も時計がズレるように絶対ではありませんが結果的にPCのタイマーが持つ時間軸にすりあわされてタイミングが一致するわけです。
連続した時間軸をひとつ選択して唯一絶対とし、それにすり合わせることでタイミングを合わせることができるのです。
今回の質問のプログラムがうまくいったのも音楽の再生時間を基準と決めたからです。
音楽の再生時間が正確だからではありませんよ。
違う曲であれば基準が違うので異なる値を返したところで比較することもなく問題ありませんよね。かなたん さんが書きました:たとえば曲の長さ1分のAと曲の長さ2分のBがあったとき、もし再生位置は同じ30秒だとしても、getPositionはAでは1/2000、Bでは1/4000とことなる値を返しますよね?
そういうことを言いたくて書いたのですが・・・私の書き方がよくなくてうまく伝わらなかったようで。
BがAを倍の時間で演奏したものなら、Aの30秒の位置はBの60秒の位置ですからどちらも0.5ですし、Bの30秒の位置はAの15秒の位置ですからどちらも0.25です。
太鼓を流すタイミングは間違いなく共有できますよね。
相対位置で管理しても同じですよ。かなたん さんが書きました:もし曲のテンポに合わせて複数のデータを用意することにすると、曲の長さもそうですし同じ部分でも再生位置が変わってきますが、私はそのときは指定している時間に今のテンポ/元のテンポをかけてやればいいかなと。
でも、openFrameworksの中の人などは、相対位置で管理できた方がnoteの蓄積そのままと比較できていいと思うんですね。
変更があったとき相対位置で管理していると変更箇所が少なくて済むんですよ。
相対位置で作るようにするとそもそも元の曲が出来上がってなくても、楽譜だけで太鼓のデータを打ち込めますし、楽譜(音符の長さの合計)だけでプログラムを作ることができます。
分業が可能になります。
ひとりで作業するとしても工程順に縛られないので効率を上げる余地が広がります。
元の曲に合わせるというのは元の曲が出来上がるまで他の作業が出来なくなるということです。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
返信が遅れました・・・
openFrameworksで作ったブロック崩しをprocessingに移植させてみたのですが、似ている部分が多くて思っていたより簡単にできました。
processingってデフォルトでフレームレート60に設定されてるんですね。
(processingでもたぶんそのままでは60ちょうどではないんだろうけど。)
もしSetTimerで500ミリ秒に設定していてもOnTimer正確には500ミリ秒ごとに呼ばれているわけではないとしても、それに自分が気が付いていなければそれでいいかな。とか。
でも、曲とかを使うとSetTimerなどとずれてくる可能性もあるので・・・
とりあえず、プログラム内共通で頼れるミリ秒があればいいんですけどね。
複雑になると面倒なので、ないならないであるものでどうにかするしかないですけど。
OpenCVは最初一緒に最新版を入れたのですが、Vistaのせいかほかの環境のせいか、私の7での環境でサンプルが動いても知り合いのVistaの環境では~.dll(名前は忘れました)が見つかりませんとか言われてサンプルが動きませんでした。
そこで、知り合いのほうは古いOpenCVを入れてみたところ、サンプルをきちんと動かすことができました。
たとえば、
[hr]
[[ドン]を送る] ドンの太鼓を流すための関数呼び出し
[(1.5)秒待つ] wait
[[ドン]を送る]
[(0.5)秒待つ]
[hr]
のようにして太鼓を流すようにしています。
曲もただ流すだけで、今どこらへんかと言うのは利用していません。というかScratchではできません。
もしタイマーと曲の間などで誤差があるなら、このようにしていては誤差が生じますよね?
ということは、Scratchでは待つにしても曲を流すことにしてもスプライト(画像)を移動させることにしても、すべて私の思っているように動いてくれているということですよね?
今曲がどの辺まで行っているのかを利用することによって、太鼓と曲をきちんと同期できるようになったんですよね。
これなら、もしも曲が作ったテンポより遅れてしまってもきちんと同期されることができると。
(太鼓の達人ではこのようなことはしたりしないでしょうけど。)
確かに同じ曲でテンポを変えただけなら、相対も便利ですけど。
曲は決まっていてもテンポが決まっていない時は、音の配置だけは確定しているでしょうから、相対で作っておけば大体変更いらないでしょうね。
processingはJavaなんですね。softya(ソフト屋) さんが書きました:ちなみにopenFrameworksの実装はC++ですがprocessingの実装はJavaです。
openFrameworksで作ったブロック崩しをprocessingに移植させてみたのですが、似ている部分が多くて思っていたより簡単にできました。
processingってデフォルトでフレームレート60に設定されてるんですね。
(processingでもたぶんそのままでは60ちょうどではないんだろうけど。)
ライブラリを作ったことはないですが、そういうことができれば自分が作りやすいようにすることができますね。softya(ソフト屋) さんが書きました:processing本体にはサウンドがなくて別のライブラリを組み合わせます。
そういう意味では、openFrameworks用に自分で使いやすいライブラリを作ってやるというのは悪い方法ではないでしょう。
サウンドの再生位置ではなく、サウンドの再生時間を返す事ができるサウンドクラスを追加するのです。
そうすれば、お望みのサウンドの時間での管理になります。
[hr]
かなたんさんが相対位置で管理するライブラリを用意してあげれば解決する問題だと思います。
きっちり現実などのミリ秒と同じでなくても、自分でプログラムを組む時にすべてミリ秒単位で表記できたらいいなと言うだけで。softya(ソフト屋) さんが書きました:もし絶対的にCPUの時間基準で管理したいのであればサウンドも画像もすべてそちらに同期させる必要が有りますが、それは全てプログラマーの管理で行う必要がありWindowsOSやAPIはそこまでの厳密な時間管理を行なっていませんので理解してくださいね。
時間管理を主体としたOSもあります。逆に言えばRTOSであると明言していないOSは時間管理に限界があると言うことです。
もしSetTimerで500ミリ秒に設定していてもOnTimer正確には500ミリ秒ごとに呼ばれているわけではないとしても、それに自分が気が付いていなければそれでいいかな。とか。
でも、曲とかを使うとSetTimerなどとずれてくる可能性もあるので・・・
とりあえず、プログラム内共通で頼れるミリ秒があればいいんですけどね。
複雑になると面倒なので、ないならないであるものでどうにかするしかないですけど。
今回は知り合いのVistaで動けばいいので、そのパソコンで動くものを作っていこうと思います。softya(ソフト屋) さんが書きました:もし出来るだけ多くの人に配布するなら最悪のパターンに合わせる必要性が出てくるでしょう。二人のPCでしか動かさないなら悪い方に合わせるだけでしょう。
OpenCVはバージョン合わせるだけなのでさほどの問題とも思えません。
OpenCVは最初一緒に最新版を入れたのですが、Vistaのせいかほかの環境のせいか、私の7での環境でサンプルが動いても知り合いのVistaの環境では~.dll(名前は忘れました)が見つかりませんとか言われてサンプルが動きませんでした。
そこで、知り合いのほうは古いOpenCVを入れてみたところ、サンプルをきちんと動かすことができました。
ソフトで作っている間も、実は設定した通りではなかったのでしょうか?softya(ソフト屋) さんが書きました:根本的な問題として、一般的な液晶モニタのリフレッシュレートが1/60なので1/100で作っても実際問題意味が無いのです。
比率で言えば5コマの内3コマしか表示されません。つまり1/100の精度は必要なかったと思います。
前述のようにScratchで「起動してからの経過時間」を調べることは容易ですが、そのプログラムでは利用していません。ISLe さんが書きました:それは相対時間ではなくて「起動してからの経過時間」という基準に合わせたからですよ。
プログラムの相対速度が違ってもPCのタイマーが唯一絶対の時間軸となっているのです。
500ミリ秒経ったらまた500ミリ秒経つまで待つ、というふうにするとズレが蓄積していきますが、起動してからの経過時間は都度ズレても誤差を蓄積しません。
音楽再生は音楽再生の方で頑張ってPCのタイマーに合わせてくれます。
いまどきのPCなら音楽再生が遅延することはないと思います。保証はありませんが。
またPCのタイマー自体も時計がズレるように絶対ではありませんが結果的にPCのタイマーが持つ時間軸にすりあわされてタイミングが一致するわけです。
たとえば、
[hr]
[[ドン]を送る] ドンの太鼓を流すための関数呼び出し
[(1.5)秒待つ] wait
[[ドン]を送る]
[(0.5)秒待つ]
[hr]
のようにして太鼓を流すようにしています。
曲もただ流すだけで、今どこらへんかと言うのは利用していません。というかScratchではできません。
もしタイマーと曲の間などで誤差があるなら、このようにしていては誤差が生じますよね?
ということは、Scratchでは待つにしても曲を流すことにしてもスプライト(画像)を移動させることにしても、すべて私の思っているように動いてくれているということですよね?
はい。ISLe さんが書きました:連続した時間軸をひとつ選択して唯一絶対とし、それにすり合わせることでタイミングを合わせることができるのです。
今回の質問のプログラムがうまくいったのも音楽の再生時間を基準と決めたからです。
音楽の再生時間が正確だからではありませんよ。
今曲がどの辺まで行っているのかを利用することによって、太鼓と曲をきちんと同期できるようになったんですよね。
これなら、もしも曲が作ったテンポより遅れてしまってもきちんと同期されることができると。
もし曲の流れや長さにかかわらず再生してから一定時間(単位は秒またはミリ秒)経ったら処理を行いたい場合は、全体のどれくらい(割合)より初めからどれくらい(秒またはミリ秒)のほうが便利ですよね。ISLe さんが書きました:違う曲であれば基準が違うので異なる値を返したところで比較することもなく問題ありませんよね。
BがAを倍の時間で演奏したものなら、Aの30秒の位置はBの60秒の位置ですからどちらも0.5ですし、Bの30秒の位置はAの15秒の位置ですからどちらも0.25です。
太鼓を流すタイミングは間違いなく共有できますよね。
(太鼓の達人ではこのようなことはしたりしないでしょうけど。)
確かに同じ曲でテンポを変えただけなら、相対も便利ですけど。
私が作るときは曲をあらかじめ作ってからプログラムを作りますが、他人と共同でとなると必ずしもプログラムを作る前に曲ができているとは限りませんね。ISLe さんが書きました:相対位置で管理しても同じですよ。
変更があったとき相対位置で管理していると変更箇所が少なくて済むんですよ。
相対位置で作るようにするとそもそも元の曲が出来上がってなくても、楽譜だけで太鼓のデータを打ち込めますし、楽譜(音符の長さの合計)だけでプログラムを作ることができます。
分業が可能になります。
ひとりで作業するとしても工程順に縛られないので効率を上げる余地が広がります。
元の曲に合わせるというのは元の曲が出来上がるまで他の作業が出来なくなるということです。
曲は決まっていてもテンポが決まっていない時は、音の配置だけは確定しているでしょうから、相対で作っておけば大体変更いらないでしょうね。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
間違いなく液晶のリフレッシュレートは超えられません。なので、設定した通りのものが見えていなかったでしょう。かなたん さんが書きました:ソフトで作っている間も、実は設定した通りではなかったのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
あらかじめ曲ありき且つデータテーブルを作成した後にいっさい曲を変更しないという前提でも、手間は同じだと思います。かなたん さんが書きました:もし曲の流れや長さにかかわらず再生してから一定時間(単位は秒またはミリ秒)経ったら処理を行いたい場合は、全体のどれくらい(割合)より初めからどれくらい(秒またはミリ秒)のほうが便利ですよね。
盛り上げるためにサビを増やすとか収録時間の都合でカットとか曲を変更する可能性は多分にあります。
「初めからどれくらい(秒またはミリ秒)のほうが便利」と感じることはまったくないですね。
そもそもデータテーブルがミリ秒単位かどうか気になるのがおかしいですよね。
テータテーブルの中身を直接触るのは非効率です。
楽譜データから変換できないのでしょうか。
楽譜が手書きだったりライブ音源だったりするのでしょうか。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
指定の速さで動くようコマを調整したら思ったように見えなくなるかもしれないとか思っていましたが、別にその時見えているのがすでにコマ落ちしている(?)から、コマを調整してもたぶん問題なかったのですね。softya(ソフト屋) さんが書きました:間違いなく液晶のリフレッシュレートは超えられません。なので、設定した通りのものが見えていなかったでしょう。
曲の再生位置に関しては、どんなときでも初めからよりも全体のどれくらいの方がいいのですね。ISLe さんが書きました:あらかじめ曲ありき且つデータテーブルを作成した後にいっさい曲を変更しないという前提でも、手間は同じだと思います。
盛り上げるためにサビを増やすとか収録時間の都合でカットとか曲を変更する可能性は多分にあります。
「初めからどれくらい(秒またはミリ秒)のほうが便利」と感じることはまったくないですね。
たとえば、
2分の5秒目は1/24、後ろ一分ごっそりカットすると1分の5秒目になって1/12。
と値変わりますよね。
こんなことするかどうか―ですが、こんなときでも割合の方が便利ですか?
割合の値が変わっても曲の長さかけてやれば同じ値になるから、別に困ることないのか・・・
音源は作曲ソフトで作ったものを利用しています。ISLe さんが書きました:そもそもデータテーブルがミリ秒単位かどうか気になるのがおかしいですよね。
テータテーブルの中身を直接触るのは非効率です。
楽譜データから変換できないのでしょうか。
楽譜が手書きだったりライブ音源だったりするのでしょうか。
noteの値は、最初はテンポやフレームレートを頼りに決めました。
ドレミの歌は♪=120だから2拍で1秒。
1秒で60フレーム表示されるはずだから、付点四分音符だと45フレーム。
のように。
最初は差分を書いていて、後で差分でなく最初からの合計を書いた方が判定するときにいいんじゃないかとも思ったけど、その時は別にその差分を利用できるようにすればいいやでやってました。
(結局フレームレートは当てにならずにうまくいきませんでしたが。)
で、時間同期等でやるとなったときには、フレーム単位だったのを全てミリ秒単位に変換させました。
元を変えずともその数を変換してやればそのまま使えるでしょうけど、私はこのほうがいいと思って元を書き換えました。
もしこの後別単位でやるとなったときは、私はさらにその別単位に直すでしょう。
そのほうが、私にとっては作っていて使っていてわかりやすいんですよ。
出来るだけ値そのまま使えますし。
でも自分が一番見てわかりやすい値にしておいて必要に応じて計算して使うほうが、デバッグなどの時にわかりやすいだろうか・・・?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
人間が分かりやすい値とコンピューターで処理しやすい値は別だと考えてもらった方が良いでしょう。
なのでプログラム開始時に内部で処理しやす形に一度変換してやれば良いと思います。
なのでプログラム開始時に内部で処理しやす形に一度変換してやれば良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
そういうことならかなたんさんのやりやすいようにするのがいちばんかもしれないですね。かなたん さんが書きました:音源は作曲ソフトで作ったものを利用しています。
noteの値は、最初はテンポやフレームレートを頼りに決めました。
ドレミの歌は♪=120だから2拍で1秒。
1秒で60フレーム表示されるはずだから、付点四分音符だと45フレーム。
のように。
最初は差分を書いていて、後で差分でなく最初からの合計を書いた方が判定するときにいいんじゃないかとも思ったけど、その時は別にその差分を利用できるようにすればいいやでやってました。
(結局フレームレートは当てにならずにうまくいきませんでしたが。)
で、時間同期等でやるとなったときには、フレーム単位だったのを全てミリ秒単位に変換させました。
元を変えずともその数を変換してやればそのまま使えるでしょうけど、私はこのほうがいいと思って元を書き換えました。
もしこの後別単位でやるとなったときは、私はさらにその別単位に直すでしょう。
そのほうが、私にとっては作っていて使っていてわかりやすいんですよ。
出来るだけ値そのまま使えますし。
でも自分が一番見てわかりやすい値にしておいて必要に応じて計算して使うほうが、デバッグなどの時にわかりやすいだろうか・・・?
わたしはデータテーブルの中身を見ないので分かりやすいかどうか気にすることもないんです。
どうやらデータテーブルがおかしいとなればデータテーブルを作成するプログラムをデバッグします。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
softya(ソフト屋) さんが書きました:人間が分かりやすい値とコンピューターで処理しやすい値は別だと考えてもらった方が良いでしょう。
なのでプログラム開始時に内部で処理しやす形に一度変換してやれば良いと思います。
今回は最終的にうまくいきましたが、うまくいくまでにデータテーブルの値と比較させたい値とを比較するタイミングで出力させるなどして確認したりもしました。ISLe さんが書きました: そういうことならかなたんさんのやりやすいようにするのがいちばんかもしれないですね。
わたしはデータテーブルの中身を見ないので分かりやすいかどうか気にすることもないんです。
どうやらデータテーブルがおかしいとなればデータテーブルを作成するプログラムをデバッグします。
音と太鼓がうまく合わないとなるとそうやって関係ありそうな値を出力させておいて、どちらが間違っているのかをチェックしたりしました。
だんだんうまく合わないなら後者の値を確認して、急にうまく合わなくなれば前者の値を確認しました。
今回に限らず、変数を使っていてうまくいかなければ、配列でもそうでなくても怪しげな変数の値をチェックします。
人間が分かりやすい値とコンピューターで処理しやすい値は別だというのはいろいろとやっていてわかりました。
自作関数などのでは自分の思った通りにできますが、既に用意されているものだと必ずしも自分の思っているそのままに使えるとは限らないですもんね。
Re: openFrameworks プログラムで曲を流すと、他の処理が遅くなる。
間違っているかどうかわからないものを2つ以上掛け合わせたら、正しいかどうかも分からなくなってしまいますから、運任せになりますよ?かなたん さんが書きました:音と太鼓がうまく合わないとなるとそうやって関係ありそうな値を出力させておいて、どちらが間違っているのかをチェックしたりしました。
だんだんうまく合わないなら後者の値を確認して、急にうまく合わなくなれば前者の値を確認しました。
今回に限らず、変数を使っていてうまくいかなければ、配列でもそうでなくても怪しげな変数の値をチェックします。
正しく動いているように見えても、間違った同士の結果が偶然そう見えるだけかもしれません。
いままでのやり取りからするとそれで良いのかもしれませんが。
完成させるより試行錯誤している方が楽しいこともありますしね。
確実にひとつずつ潰さないと効率以前の問題です。
例えばデータテーブルを使わずに、1拍毎に1個太鼓を出すコード(ほんの1行程度)を埋め込んで、曲とテンポが合うかどうかでプログラムのタイミングのとり方に問題があるかどうか明確になります。
結果を見て分かりやすい楽譜を用意すればデータテーブルのチェックも楽になります。
分かってないように感じますね。かなたん さんが書きました:人間が分かりやすい値とコンピューターで処理しやすい値は別だというのはいろいろとやっていてわかりました。
人間が分かりやすいとコンピューターで処理しにくい、人間が分かりにくいとコンピューターで処理しやすい、と思っていませんか?
それは直接比較したらの話であって、直接比較しなければ良いのです。
人間が見たり触ったりするところだけ、人間にとって分かりやすくなっていれば良いのです。
そしてあちこち人間が見たり触ったりするのは非効率なことです。
これまでのやり取りで、「コンピュータの世界で自分の思っているように使えるものは何一つ無い」ということは伝わりませんでしたかね。かなたん さんが書きました:自作関数などのでは自分の思った通りにできますが、既に用意されているものだと必ずしも自分の思っているそのままに使えるとは限らないですもんね。