質問するログイン新規登録

質問編集履歴

2

プログラムを「ボタンを押したら録音を開始, もう一度押したら停止」となるように変更しました。またその過程で、言語を「Kotlin」から「Java」へと変更しました。

2019/04/16 04:12

投稿

oto.
oto.

スコア10

title CHANGED
File without changes
body CHANGED
@@ -1,162 +1,133 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
- 現在、androidstudio(Kotlin)にてAudioRecordで音を録り、音の大きさに応じて
3
+ 現在、androidstudioにてAudioRecordで音を録り、音の大きさに応じて
4
4
  アプリ画面全体の色をリアルタイムに変えるというアプリを作りたいと思っています。
5
+ 言語はKotlinを想定していましたが、情報を集めきれず、Javaに路線変更いたしました。
5
6
 
6
7
  色は五段階程度を想定しております。
7
8
 
8
-
9
- AudioRecord中のLog.vの内容を
10
- 何かのビューに出力すれば良いか
9
+ 「録音」表示されたボタンを押す
10
+
11
+ 録音を開始し、ボタンの表示が「停止」になる
12
+
13
+ 「停止」と表示されたボタンを押すと、録音は停止し、ファイル名「sample.3gp」にて音声が保存される。
11
- 思ってるのですが、具体的にどのようにすればいかわからず
14
+ いうプログラムをJavaて(見う見まねで)作成しました。
15
+ しかし、「音量のログを表示する」「そのログを用いて画面を変化させる」という作業が
12
- っておりま
16
+ どのように記せばよいかわかっておりません…
17
+ 具体的にどのような処理をすればログを取得(あるいは表示)することができるのでしょう…。
13
18
  ご教示いただけないでしょうか。
14
19
 
15
20
 
16
21
  ### 該当のソースコード
17
22
 
23
+ 「録音」と表示されたボタンを押す
24
+
25
+ 録音を開始し、ボタンの表示が「停止」になる
26
+
18
- デモンストレーションとして画面表示された『開始』ボタンを押すと、『運勢』という文字が『大吉』変わ」というプログラムを書きました
27
+ 停止」と表示されたボタンを押すと、録音は停止し、ファイル名「sample.3gp」て音声が保存される。
19
- そこに AudioRecordクラスを追加し、改造していきたいと思っております。
20
28
 
21
29
 
22
30
  ```MainActivity
23
31
 
24
- package com.example.myapplication
32
+ package com.example.test_recorder0415;
25
33
 
26
- import android.support.v7.app.AppCompatActivity
34
+ import android.support.v7.app.AppCompatActivity;
27
- import android.os.Bundle
35
+ import android.os.Bundle;
36
+ import java.io.IOException;
28
- import android.view.View
37
+ import android.app. Activity;
29
- import kotlinx.android.synthetic.main.activity_main.*
30
- import android.media.AudioFormat
31
- import android.media.AudioRecord
32
- import android.media.MediaRecorder
38
+ import android.media.MediaRecorder;
39
+ import android.os.Bundle;
33
- import android.util.Log
40
+ import android.view.Menu;
34
- import kotlin.math.max
41
+ import android.view.View;
42
+ import android.widget. Button;
35
43
 
36
44
 
37
- class MainActivity : AppCompatActivity() {
45
+ public class MainActivity extends AppCompatActivity {
38
46
 
47
+ private MediaRecorder rec;
48
+ boolean isRec= false; //G, 中カどうか
49
+ @Override
39
- override fun onCreate(savedInstanceState: Bundle?) {
50
+ public void onCreate(Bundle savedInstanceState) {
40
- super.onCreate(savedInstanceState)
51
+ super.onCreate(savedInstanceState);
41
- setContentView(R.layout.activity_main)
52
+ setContentView(R. layout.activity_main);
53
+ // MediaRecorderオブジェクトを準備
54
+ rec=new MediaRecorder();
42
55
  }
56
+ // [録音]/. [停止]ボタンがクリックされた時の処理
57
+ public void onClick(View view) {
58
+ Button btnRecord = (Button) findViewById(R.id.btnRecord);
43
59
 
60
+ //録音停止中の場合
44
61
 
62
+ if (!isRec) {
63
+ // MediaRecorderオブジェクトの準備
64
+ rec.setAudioSource(MediaRecorder.AudioSource.MIC);
65
+ rec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
66
+ rec.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
67
+ rec.setOutputFile("/mnt/sdcard/sample.3gp");
68
+ try {
69
+ rec.prepare();
70
+ } catch (IllegalStateException e) {
71
+ e.printStackTrace();
45
- fun onButton(v: View) {
72
+ } catch (IOException e) {
46
- tv.text = "大吉"
73
+ e.printStackTrace();
47
- }
74
+ }
75
+ //録音開始
48
76
 
77
+ rec.start();
78
+ isRec = true;
79
+ btnRecord.setText("停止");
49
80
 
81
+ //録音中の場合、録音を停止
50
- /**
82
+ } else {
51
- * AudioRecord クラスのサンプルコード
52
- */
53
- class AudioRecordSample {
54
83
 
55
- // サンプリングレート (Hz)
56
- // 全デバイスサポート保障は44100のみ
57
- private val samplingRate = 44100
58
-
59
- // フレームレート (fps)
60
- // 1秒間に何回音声データを処理したいか
61
- // 各自好きに決める
84
+ rec.stop();
62
- private val frameRate = 10
85
+ rec.reset();
63
-
64
- // 1フレームの音声データ(=Short値)の数
65
- private val oneFrameDataCount = samplingRate / frameRate
66
-
67
- // 1フレームの音声データのバイト数 (byte)
68
- // Byte = 8 bit, Short = 16 bit なので, Shortの倍になる
69
- private val oneFrameSizeInByte = oneFrameDataCount * 2
70
-
71
- // 音声データのバッファサイズ (byte)
72
- // 要件1:oneFrameSizeInByte より大きくする必要がある
73
- // 要件2:デバイスの要求する最小値より大きくする必要がある
74
- private val audioBufferSizeInByte =
75
- max(
76
- oneFrameSizeInByte * 10, // 適当に10フレーム分のバッファを持たせた
77
- android.media.AudioRecord.getMinBufferSize(
78
- samplingRate,
86
+ isRec = false;
79
- AudioFormat.CHANNEL_IN_MONO,
80
- AudioFormat.ENCODING_PCM_16BIT
81
- )
82
- )
83
-
84
- fun startRecording() {
85
-
86
- // インスタンスの作成
87
- val audioRecord = AudioRecord(
88
- MediaRecorder.AudioSource.MIC, // 音声のソース
89
- samplingRate, // サンプリングレート
90
- AudioFormat.CHANNEL_IN_MONO, // チャネル設定. MONO and STEREO が全デバイスサポート保障
91
- AudioFormat.ENCODING_PCM_16BIT, // PCM16が全デバイスサポート保障
92
- audioBufferSizeInByte
93
- ) // バッファ
94
-
95
- // 音声データを幾つずつ処理するか( = 1フレームのデータの数)
96
- audioRecord.positionNotificationPeriod = oneFrameDataCount
97
-
98
- // ここで指定した数になったタイミングで, 後続の onMarkerReached が呼び出される
99
- // 通常のストリーミング処理では必要なさそう?
100
- audioRecord.notificationMarkerPosition = 40000 // 使わないなら設定しない.
101
-
102
- // 音声データを格納する配列
103
- val audioDataArray = ShortArray(oneFrameDataCount)
104
-
105
- // コールバックを指定
106
- audioRecord.setRecordPositionUpdateListener(object : AudioRecord.OnRecordPositionUpdateListener {
107
-
108
- // フレームごとの処理
109
- override fun onPeriodicNotification(recorder: AudioRecord) {
110
- recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
111
- Log.v("AudioRecord", "onPeriodicNotification size=${audioDataArray.size}")
112
- // 好きに処理する
113
- }
114
-
115
- // マーカータイミングの処理.
116
- // notificationMarkerPosition に到達した際に呼ばれる
117
- override fun onMarkerReached(recorder: AudioRecord) {
118
- recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
119
- Log.v("AudioRecord", "onMarkerReached size=${audioDataArray.size}")
120
- // 好きに処理する
121
- }
122
- })
123
-
124
- audioRecord.startRecording()
87
+ btnRecord.setText("録音");
125
88
  }
126
89
  }
90
+ @Override
91
+ protected void onDestroy() {
92
+ super.onDestroy();
93
+ rec.release();
94
+ }
127
95
  }
128
96
  ```
129
97
  ```activitymain
130
98
  <?xml version="1.0" encoding="utf-8"?>
131
- <android.support.constraint.ConstraintLayout
99
+ <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
132
- xmlns:android="http://schemas.android.com/apk/res/android"
100
+ xmlns:app="http://schemas.android.com/apk/res-auto"
133
- xmlns:tools="http://schemas.android.com/tools"
101
+ xmlns:tools="http://schemas.android.com/tools"
134
- xmlns:app="http://schemas.android.com/apk/res-auto"
135
- android:layout_width="match_parent"
102
+ android:layout_width="match_parent"
136
- android:layout_height="match_parent"
103
+ android:layout_height="match_parent"
137
- tools:context=".MainActivity">
104
+ tools:context=".MainActivity">
138
105
 
139
106
  <TextView
140
- android:id="@+id/tv"
141
- android:layout_width="wrap_content"
107
+ android:layout_width="wrap_content"
142
- android:layout_height="wrap_content"
108
+ android:layout_height="wrap_content"
143
- android:text="今日の運勢"
109
+ android:text="Hello World!"
144
- android:textSize="50sp"
145
- app:layout_constraintBottom_toBottomOf="parent"
110
+ app:layout_constraintBottom_toBottomOf="parent"
146
- app:layout_constraintLeft_toLeftOf="parent"
111
+ app:layout_constraintLeft_toLeftOf="parent"
147
- app:layout_constraintRight_toRightOf="parent"
112
+ app:layout_constraintRight_toRightOf="parent"
148
- app:layout_constraintTop_toTopOf="parent"/>
113
+ app:layout_constraintTop_toTopOf="parent" />
114
+
149
115
  <Button
116
+ android:id="@+id/btnRecord"
150
- android:onClick="onButton"
117
+ android:layout_width="match_parent"
151
- android:text="開始"
152
- android:layout_width="wrap_content"
118
+ android:layout_height="wrap_content"
153
- android:layout_height="wrap_content" tools:layout_editor_absoluteY="433dp"
119
+ android:layout_alignParentLeft="true"
120
+ android:layout_alignParentTop="true"
121
+ android:onClick="onClick"
154
- tools:layout_editor_absoluteX="174dp"/>
122
+ android:text="録音" />
155
123
 
124
+
156
125
  </android.support.constraint.ConstraintLayout>
157
126
  ```
158
127
 
159
128
  ### 試したこと
129
+ マニフェストには「マイク」と「SDカード」の利用許可を入れております。
130
+ 上記のソースコードにて、録音しそれをSDカードに保存することはできたのですが
160
- Handlerを用いて定期的描画を続ければよいのかと思ったのですが、実装に至っておりません。
131
+ 録音中(録音る音)音量を取得るということできておりません。
161
132
  非常に初歩的な質問で申し訳ありませんが
162
133
  ご教示いただけましたら幸いです。

1

プログラミングコードの追加

2019/04/16 04:11

投稿

oto.
oto.

スコア10

title CHANGED
File without changes
body CHANGED
@@ -1,8 +1,11 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
3
  現在、androidstudio(Kotlin)にてAudioRecordで音を録り、音の大きさに応じて
4
- 画面全体の色をリアルタイムに変えるというアプリを作りたいと思っています。
4
+ アプリ画面全体の色をリアルタイムに変えるというアプリを作りたいと思っています。
5
5
 
6
+ 色は五段階程度を想定しております。
7
+
8
+
6
9
  AudioRecord中のLog.vの内容を
7
10
  何かのビューに出力すれば良いかと
8
11
  思っているのですが、具体的にどのようにすればよいかわからず
@@ -12,55 +15,147 @@
12
15
 
13
16
  ### 該当のソースコード
14
17
 
15
- ```Kotlin
18
+ デモンストレーションとして「画面表示された『開始』ボタンを押すと、『運勢』という文字が『大吉』に変わる」というプログラムを書きました。
16
- import ....
19
+ そこに AudioRecordクラスを追加し、改造していきたいと思っております。
17
20
 
18
- class AudioRecordSample {
19
21
 
20
- private val samplingRate = 44100
21
- private val frameRate = 10
22
+ ```MainActivity
22
23
 
23
- private val oneFrameDataCount = samplingRate / frameRate
24
- private val oneFrameSizeInByte = oneFrameDataCount * 2
24
+ package com.example.myapplication
25
25
 
26
+ import android.support.v7.app.AppCompatActivity
27
+ import android.os.Bundle
26
- private val audioBufferSizeInByte =
28
+ import android.view.View
27
- max(oneFrameSizeInByte * 10, // 適当に10フレーム分のバッファを持たせた
29
+ import kotlinx.android.synthetic.main.activity_main.*
30
+ import android.media.AudioFormat
28
- android.media.AudioRecord.getMinBufferSize(samplingRate,
31
+ import android.media.AudioRecord
32
+ import android.media.MediaRecorder
29
- AudioFormat.CHANNEL_IN_MONO,
33
+ import android.util.Log
30
- AudioFormat.ENCODING_PCM_16BIT))
34
+ import kotlin.math.max
31
35
 
32
- fun startRecording() {
33
36
 
37
+ class MainActivity : AppCompatActivity() {
38
+
39
+ override fun onCreate(savedInstanceState: Bundle?) {
40
+ super.onCreate(savedInstanceState)
41
+ setContentView(R.layout.activity_main)
42
+ }
43
+
44
+
45
+ fun onButton(v: View) {
46
+ tv.text = "大吉"
47
+ }
48
+
49
+
50
+ /**
51
+ * AudioRecord クラスのサンプルコード
52
+ */
53
+ class AudioRecordSample {
54
+
55
+ // サンプリングレート (Hz)
56
+ // 全デバイスサポート保障は44100のみ
57
+ private val samplingRate = 44100
58
+
59
+ // フレームレート (fps)
60
+ // 1秒間に何回音声データを処理したいか
61
+ // 各自好きに決める
62
+ private val frameRate = 10
63
+
64
+ // 1フレームの音声データ(=Short値)の数
65
+ private val oneFrameDataCount = samplingRate / frameRate
66
+
67
+ // 1フレームの音声データのバイト数 (byte)
68
+ // Byte = 8 bit, Short = 16 bit なので, Shortの倍になる
69
+ private val oneFrameSizeInByte = oneFrameDataCount * 2
70
+
71
+ // 音声データのバッファサイズ (byte)
72
+ // 要件1:oneFrameSizeInByte より大きくする必要がある
73
+ // 要件2:デバイスの要求する最小値より大きくする必要がある
74
+ private val audioBufferSizeInByte =
75
+ max(
76
+ oneFrameSizeInByte * 10, // 適当に10フレーム分のバッファを持たせた
77
+ android.media.AudioRecord.getMinBufferSize(
78
+ samplingRate,
79
+ AudioFormat.CHANNEL_IN_MONO,
80
+ AudioFormat.ENCODING_PCM_16BIT
81
+ )
82
+ )
83
+
84
+ fun startRecording() {
85
+
86
+ // インスタンスの作成
34
- val audioRecord = AudioRecord(
87
+ val audioRecord = AudioRecord(
35
88
  MediaRecorder.AudioSource.MIC, // 音声のソース
36
89
  samplingRate, // サンプリングレート
37
90
  AudioFormat.CHANNEL_IN_MONO, // チャネル設定. MONO and STEREO が全デバイスサポート保障
38
91
  AudioFormat.ENCODING_PCM_16BIT, // PCM16が全デバイスサポート保障
39
- audioBufferSizeInByte) // バッファ
92
+ audioBufferSizeInByte
93
+ ) // バッファ
40
94
 
95
+ // 音声データを幾つずつ処理するか( = 1フレームのデータの数)
41
- audioRecord.positionNotificationPeriod = oneFrameDataCount
96
+ audioRecord.positionNotificationPeriod = oneFrameDataCount
42
- audioRecord.notificationMarkerPosition = 40000 // 使わないなら設定しない.
43
97
 
98
+ // ここで指定した数になったタイミングで, 後続の onMarkerReached が呼び出される
99
+ // 通常のストリーミング処理では必要なさそう?
44
- val audioDataArray = ShortArray(oneFrameDataCount)
100
+ audioRecord.notificationMarkerPosition = 40000 // 使わないなら設定しない.
45
101
 
102
+ // 音声データを格納する配列
46
- audioRecord.setRecordPositionUpdateListener(object : AudioRecord.OnRecordPositionUpdateListener {
103
+ val audioDataArray = ShortArray(oneFrameDataCount)
47
104
 
48
- override fun onPeriodicNotification(recorder: AudioRecord) {
49
- recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声デタ読込
105
+ // ルバックを指定
50
- Log.v("AudioRecord", "onPeriodicNotification size=${audioDataArray.size}")
106
+ audioRecord.setRecordPositionUpdateListener(object : AudioRecord.OnRecordPositionUpdateListener {
51
- }
52
107
 
108
+ // フレームごとの処理
53
- override fun onMarkerReached(recorder: AudioRecord) {
109
+ override fun onPeriodicNotification(recorder: AudioRecord) {
54
- recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
110
+ recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
55
- Log.v("AudioRecord", "onMarkerReached size=${audioDataArray.size}")
111
+ Log.v("AudioRecord", "onPeriodicNotification size=${audioDataArray.size}")
112
+ // 好きに処理する
56
- }
113
+ }
57
- })
58
114
 
115
+ // マーカータイミングの処理.
116
+ // notificationMarkerPosition に到達した際に呼ばれる
117
+ override fun onMarkerReached(recorder: AudioRecord) {
118
+ recorder.read(audioDataArray, 0, oneFrameDataCount) // 音声データ読込
119
+ Log.v("AudioRecord", "onMarkerReached size=${audioDataArray.size}")
120
+ // 好きに処理する
121
+ }
122
+ })
123
+
59
- audioRecord.startRecording()
124
+ audioRecord.startRecording()
125
+ }
60
126
  }
61
127
  }
62
128
  ```
129
+ ```activitymain
130
+ <?xml version="1.0" encoding="utf-8"?>
131
+ <android.support.constraint.ConstraintLayout
132
+ xmlns:android="http://schemas.android.com/apk/res/android"
133
+ xmlns:tools="http://schemas.android.com/tools"
134
+ xmlns:app="http://schemas.android.com/apk/res-auto"
135
+ android:layout_width="match_parent"
136
+ android:layout_height="match_parent"
137
+ tools:context=".MainActivity">
63
138
 
139
+ <TextView
140
+ android:id="@+id/tv"
141
+ android:layout_width="wrap_content"
142
+ android:layout_height="wrap_content"
143
+ android:text="今日の運勢"
144
+ android:textSize="50sp"
145
+ app:layout_constraintBottom_toBottomOf="parent"
146
+ app:layout_constraintLeft_toLeftOf="parent"
147
+ app:layout_constraintRight_toRightOf="parent"
148
+ app:layout_constraintTop_toTopOf="parent"/>
149
+ <Button
150
+ android:onClick="onButton"
151
+ android:text="開始"
152
+ android:layout_width="wrap_content"
153
+ android:layout_height="wrap_content" tools:layout_editor_absoluteY="433dp"
154
+ tools:layout_editor_absoluteX="174dp"/>
155
+
156
+ </android.support.constraint.ConstraintLayout>
157
+ ```
158
+
64
159
  ### 試したこと
65
160
  Handlerを用いて定期的に描画をし続ければよいのかと思ったのですが、実装に至っておりません。
66
161
  非常に初歩的な質問で申し訳ありませんが