質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

815閲覧

AudioInputStream.read()の処理速度が140msと遅く改善したい。

Lapis_nul

総合スコア6

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2021/06/12 03:53

編集2021/06/13 10:46

前提・実現したいこと

外部の音声を波形として表示するプログラムを作成しています。一応、30fpsを仮定し、30ミリ秒ごとに波形を表示するものとしています。

該当のソースコード

Spectrum.java

Java

1import java.awt.BasicStroke; 2import java.awt.Graphics; 3import java.awt.Graphics2D; 4import java.awt.geom.Line2D; 5import java.io.IOException; 6 7import javax.sound.sampled.AudioFormat; 8import javax.sound.sampled.AudioInputStream; 9import javax.sound.sampled.AudioSystem; 10import javax.sound.sampled.LineUnavailableException; 11import javax.sound.sampled.TargetDataLine; 12import javax.swing.JPanel; 13 14public class Recorder extends JPanel implements Runnable { 15 16 private AudioFormat fmt; 17 private byte data[]; 18 private byte dataCopy[]; 19 private TargetDataLine line; 20 21 private static final int SAMPLE_RATE = 44100; 22 private static final int SAMPLE_BITS = 8; 23 private static final int CHANNELS = 1; 24 private static final boolean IS_SIGNED = true; 25 private static final boolean IS_BIG_ENDIEN = true; 26 private static final double READ_LENGTH = 0.03; // 30fps 27 28 private int loop; 29 private static final boolean DEBUG = true; 30 31 public Recorder() { 32 fmt = new AudioFormat(SAMPLE_RATE, SAMPLE_BITS, CHANNELS, IS_SIGNED, IS_BIG_ENDIEN); 33 data = new byte[(int) (SAMPLE_RATE * READ_LENGTH)]; 34 dataCopy = data.clone(); 35 36 try { 37 line = AudioSystem.getTargetDataLine(fmt); 38 line.open(); 39 } catch (LineUnavailableException e) { 40 e.printStackTrace(); 41 } 42 } 43 44 public void doRecord() { 45 // 別スレッドに分ける 46 Thread thread = new Thread(this); 47 thread.start(); 48 } 49 50 public void run() { 51 AudioInputStream in = new AudioInputStream(line); 52 line.start(); 53 try { 54 if (DEBUG) { 55 for (loop = 1; loop <= 100; loop++) { 56 long c0 = System.nanoTime(); 57 in.read(data, 0, data.length); 58 long c1 = System.nanoTime(); 59 dataCopy = data.clone(); // 読み取りと書き取りの衝突防止 60 long c2 = System.nanoTime(); 61 repaint(); 62 long c3 = System.nanoTime(); 63 System.out 64 .println("[Main Loop] Loop " + loop + ": " + 65 (c1 - c0)/1000000.0 + " " + (c2 - c1)/1000000.0 + " " + (c3 - c2)/1000000.0); 66 } 67 } else { 68 while (true) { 69 in.read(data, 0, data.length); 70 dataCopy = data.clone(); // 読み取りと書き取りの衝突防止 71 repaint(); 72 } 73 } 74 } catch (IOException e) { 75 e.printStackTrace(); 76 } 77 line.stop(); 78 line.close(); 79 } 80 81 @Override 82 public void paintComponent(Graphics g) { 83 long c0 = System.nanoTime(); 84 super.paintComponent(g); 85 Graphics2D g2 = (Graphics2D) g; 86 BasicStroke wideStroke = new BasicStroke(4.0f); 87 g2.setStroke(wideStroke); 88 for (int i = 0; i < data.length - 1; i++) { 89 Line2D line = new Line2D.Double( 90 toXCoodinate(i, 1000), toYCoodinate(dataCopy[i], 600), 91 toXCoodinate(i + 1, 1000), toYCoodinate(dataCopy[i + 1], 600)); 92 g2.draw(line); 93 } 94 long c1 = System.nanoTime(); 95 if (DEBUG) { 96 System.out.println("[Repeint] Loop " + loop + ": " + (c1 - c0)/1000000.0); 97 } 98 } 99 100 private int toXCoodinate(int pos, int width) { 101 double w = (double) width; 102 return (int) (pos * w / dataCopy.length); 103 } 104 105 private int toYCoodinate(byte data, int height) { 106 int amp = (int) data; 107 return (int) ((amp - 128) * (height / 255.0) * -1 + 50);//タイトルバーで隠れるので少し下げる 108 } 109} 110

###発生した課題
波形は正常に表示されているものの、想定してたものよりもFPSが非常に小さい。(おおよそ10FPS?)
プログラム実行例

試したこと

runメソッド内での各ステップごとの所要時間、およびpaintComponentメソッドの処理時間をログで表示したら以下のようになりました。特にAudioInputStream.read()の所要時間がおおよそ140ミリ秒であるか0秒であるかのどちらかであり、30ミリ秒で完結すると思っていたがかけ離れたものとなりました。ここには載せていないが、録音間隔を10ミリ秒、50ミリ秒にした場合でも同じ結果が得られました(「AudioInputStream.read()の所要時間」が「0秒」になっているループ数は異なった)。
恐らく140ミリ秒がAudioInputStream.read()の所要時間の限界であるように思えるのですが、本当にそうでしょうか。なにか改善点があったらお願いします。

[Repeint] Loop 1: 4 [Main Loop] Loop 1: 142 0 1 [Main Loop] Loop 2: 0 0 0 [Main Loop] Loop 3: 0 0 0 [Main Loop] Loop 4: 0 0 0 [Repeint] Loop 5: 3 [Repeint] Loop 5: 2 [Main Loop] Loop 5: 137 0 0 [Main Loop] Loop 6: 1 0 0 [Main Loop] Loop 7: 0 0 0 [Main Loop] Loop 8: 1 0 0 [Repeint] Loop 9: 4 [Repeint] Loop 9: 4 [Main Loop] Loop 9: 137 0 0 [Main Loop] Loop 10: 1 0 0 [Main Loop] Loop 11: 0 0 0 [Main Loop] Loop 12: 1 0 0 [Main Loop] Loop 13: 0 0 0 [Repeint] Loop 14: 4 [Main Loop] Loop 14: 139 0 0 [Main Loop] Loop 15: 0 0 2 [Repeint] Loop 15: 2 [Main Loop] Loop 16: 0 0 0 [Main Loop] Loop 17: 0 0 0 [Repeint] Loop 18: 1 [Main Loop] Loop 18: 140 0 0 [Main Loop] Loop 19: 1 0 0 [Main Loop] Loop 20: 0 0 0 (以下文字数制限のため略)

追記1

System.nanoTimeを使用した場合はこうなりました。

[Repeint] Loop 1: 3.7141 [Main Loop] Loop 1: 147.1323 0.0092 0.4591 [Main Loop] Loop 2: 0.1487 0.0016 0.0283 [Main Loop] Loop 3: 0.111 0.0018 0.0112 [Main Loop] Loop 4: 0.0723 0.0022 0.0071 [Repeint] Loop 5: 1.0374 [Repeint] Loop 5: 0.9224 [Main Loop] Loop 5: 125.0524 0.0281 0.1598 [Main Loop] Loop 6: 0.3004 0.0086 0.1049 [Main Loop] Loop 7: 0.2658 0.0218 0.0207 [Main Loop] Loop 8: 0.2519 0.0071 0.0212 [Repeint] Loop 9: 3.4221 [Repeint] Loop 9: 0.9553 [Main Loop] Loop 9: 139.1244 0.0095 0.1027 [Main Loop] Loop 10: 0.1454 0.0037 0.0404 [Main Loop] Loop 11: 0.1752 0.0071 0.0256 [Main Loop] Loop 12: 0.1436 0.0029 0.0097 [Repeint] Loop 13: 1.3418 [Repeint] Loop 13: 1.0709 [Main Loop] Loop 13: 139.2908 0.013 0.1875 [Main Loop] Loop 14: 0.3437 0.0318 0.1382 [Main Loop] Loop 15: 0.327 0.0083 0.0256 [Main Loop] Loop 16: 0.2782 0.025 0.0255 [Main Loop] Loop 17: 0.3119 0.0083 0.0496 [Repeint] Loop 18: 3.5176 [Repeint] Loop 18: 2.3505 [Main Loop] Loop 18: 138.5742 0.0124 0.1887 [Main Loop] Loop 19: 0.339 0.0096 0.1255 [Main Loop] Loop 20: 0.3278 0.0071 0.0243 (以下文字数制限のため略)

補足情報(FW/ツールのバージョンなど)

Eclipse IDE for Enterprise Java and Web Developers (includes Incubating components)
Version: 2021-03 (4.19.0)
Build id: 20210312-0638

java 16.0.1 2021-04-20
Java(TM) SE Runtime Environment (build 16.0.1+9-24)
Java HotSpot(TM) 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)

デバイス名 LAPTOP-L49P9QG6
プロセッサ Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 2.59 GHz
実装 RAM 16.0 GB (15.9 GB 使用可能)
システムの種類 64 ビット オペレーティング システム、x64 ベース プロセッサ
ペンとタッチ このディスプレイでは、ペン入力とタッチ入力は利用できません

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

あれ以来いろいろ調べてみたところ、processingというプログラム言語があるらしいので、
これを参考にしてみます。

投稿2021/06/19 14:45

Lapis_nul

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

そもそもの、計測しているタイマの精度が問題になりそうです

Javaパフォーマンス計測 そんなタイマーで大丈夫か? - プログラマーの脳みそ

投稿2021/06/12 04:25

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lapis_nul

2021/06/12 13:16

nanoTimeを使用してテストしてみました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問