未验证 提交 6bada599 编写于 作者: O openharmony_ci 提交者: Gitee

!5372 翻译完成:4024 audio文档新增状态机

Merge pull request !5372 from wusongqing/TR4024
# Audio Capture Development
---
## ***Note***:
1. This document applies to JavaScript.
---
## **Summary**
This guide will show how a JS application can use AudioCapturer to record the audio.
Applications can use the APIs provided in this document to record raw audio files.
## **AudioCapturer Framework**
The AudioCapturer interface is one of the most important components of the audio framework.
### **Audio Capturing:**
The AudioCapturer framework provides APIs for capturing raw audio files.
## **Usage**
Here's an example of how to use AudioCapturer to capture a raw audio file.
1. Use **createAudioCapturer()** to create an AudioCapturer instance. Capturer parameters can be set in **audioCapturerOptions**.\
This instance can be used to record, control, and obtain the recording status, as well as to register a callback for notifications.
```
## When to Use
You can use the APIs provided by **AudioCapturer** to record raw audio files.
### State Check
During application development, you are advised to use **on('stateChange')** to subscribe to state changes of the **AudioCapturer** instance. This is because some operations can be performed only when the audio capturer is in a given state. If the application performs an operation when the audio capturer is not in the given state, the system may throw an exception or generate other undefined behavior.
For details about the APIs, see [AudioCapturer in Audio Management](../reference/apis/js-apis-audio.md).
**Figure 1** Audio capturer state
![](figures/audio-capturer-state.png)
## How to Develop
1. Use **createAudioCapturer()** to create an **AudioCapturer** instance.
Set parameters of the **AudioCapturer** instance in **audioCapturerOptions**. This instance is used to capture audio, control and obtain the recording status, and register a callback for notification.
```js
var audioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_1,
......@@ -39,10 +42,10 @@ Here's an example of how to use AudioCapturer to capture a raw audio file.
var state = audioRenderer.state;
```
2. (Optional) Subscribe to audio capturer state change events using the **on('stateChange')** API.
If an application wants to take some action based on the state updates in capturer, the application can subscribe to the state change event.
There are more events that applications can subscribe to, such as 'markReach' and 'periodReach'. Refer to [Audio](../reference/apis/js-apis-audio.md) for more details.
```
2. (Optional) Use **on('stateChange')** to subscribe to audio renderer state changes.
If an application needs to perform some operations when the audio renderer state is updated, the application can subscribe to the state changes. For more events that can be subscribed to, see [Audio Management](../reference/apis/js-apis-audio.md).
```js
audioCapturer.on('stateChange',(state) => {
console.info('AudioCapturerLog: Changed State to : ' + state)
switch (state) {
......@@ -68,31 +71,33 @@ Here's an example of how to use AudioCapturer to capture a raw audio file.
break;
}
});
```
3. Call the **start()** function on the AudioCapturer instance to start/resume the recording task.\
The capturer state will be STATE_RUNNING once the start is complete. The application can then begin reading buffers.
```
3. Use **start()** to start audio recording.
The capturer state will be **STATE_RUNNING** once the audio capturer is started. The application can then begin reading buffers.
```js
await audioCapturer.start();
if (audioCapturer.state == audio.AudioState.STATE_RUNNING) {
console.info('AudioRecLog: Capturer started');
} else {
console.info('AudioRecLog: Capturer start failed');
}
```
4. Obtain the minimum buffer size to read using the **getBufferSize()** API.
```
4. Use **getBufferSize()** to obtain the minimum buffer size to read.
```js
var bufferSize = await audioCapturer.getBufferSize();
console.info('AudioRecLog: buffer size: ' + bufferSize);
```
5. Read the captured audio data and convert it to a byte stream. Call the **read()** API repeatedly to read the data
until the application wants to stop the recording. The following example shows how to write recorded data into a file.
```
5. Read the captured audio data and convert it to a byte stream. Call **read()** repeatedly to read the data until the application wants to stop the recording.
The following example shows how to write recorded data into a file.
```js
import fileio from '@ohos.fileio';
const path = '/data/data/.pulse_dir/capture_js.wav';
......@@ -123,7 +128,9 @@ Here's an example of how to use AudioCapturer to capture a raw audio file.
numBuffersToCapture--;
}
```
6. Once the recording is complete, call the **stop()** API on the AudioCapturer instance to stop the recording.
6. Once the recording is complete, call **stop()** to stop the recording.
```
await audioCapturer.stop();
if (audioCapturer.state == audio.AudioState.STATE_STOPPED) {
......@@ -133,8 +140,9 @@ Here's an example of how to use AudioCapturer to capture a raw audio file.
}
```
7. After the recording task is complete, call the **release()** API on the AudioCapturer instance to release the stream resources.
```
7. After the task is complete, call **release()** to release related resources.
```js
await audioCapturer.release();
if (audioCapturer.state == audio.AudioState.STATE_RELEASED) {
console.info('AudioRecLog: Capturer released');
......@@ -142,11 +150,3 @@ Here's an example of how to use AudioCapturer to capture a raw audio file.
console.info('AudioRecLog: Capturer release failed');
}
```
## **Importance of State Check**
Application developers should keep in mind that an AudioCapturer is state-based.
That is, the AudioCapturer has an internal state that the application must always check when calling recorder control APIs, because some operations are only acceptable while the capturer is in a given state.\
The system may throw an error/exception or generate other undefined behaviour if the application performs an operation while capturer is in an improper state.
## **Other APIs**
See [AudioCapturer in the Audio API](../reference/apis/js-apis-audio.md) for more useful APIs like **getAudioTime**, **getCapturerInfo** and **getStreamInfo**.
# Audio Rendering Development
---
## ***Note***:
1. This document applies to JavaScript.
---
## **Summary**
This guide will show you how to use AudioRenderer to create an audio player app.
You can use the APIs provided in this document to play audio files in output devices and manage playback tasks.
## **AudioRenderer Framework**
The AudioRenderer interface is one of the most important components of the audio framework.
### **Audio Rendering:**
The AudioRenderer framework provides APIs for playing audio files and controlling the playback.
### **Audio Interruption:**
When a higher priority stream wants to play, the AudioRenderer framework interrupts the lower priority stream.\
For example, if a call is arrived when you listen to music, the music playback, which is the lower priority stream, is paused.\
With the sample code below, we'll look at how AudioInterrupt works in detail.\
<br/>
Please see [AudioRenderer in the Audio API](../reference/apis/js-apis-audio.md#audiorenderer8) for a list of supported audio stream types and formats, such as AudioSampleFormat, AudioChannel, AudioSampleFormat, and AudioEncodingType.
## **Usage**
Here's an example of how to use AudioRenderer to play a raw audio file.
1. Use **createAudioRenderer** to create an AudioRenderer instance. Renderer parameters can be set in **audioRendererOptions**.\
This object can be used to play, control, and obtain the status of the playback, as well as receive callback notifications.
```
## When to Use
**AudioRenderer** provides APIs for rendering audio files and controlling playback. It also supports audio interruption. You can use the APIs provided by **AudioRenderer** to play audio files in output devices and manage playback tasks.
### Audio Interruption
When an audio stream with a higher priority needs to be played, the audio renderer interrupts the stream with a lower priority. For example, if a call comes in when the user is listening to music, the music playback, which is the lower priority stream, is paused. For details, see [How to Develop](#how-to-develop).
### State Check
During application development, you are advised to use **on('stateChange')** to subscribe to state changes of the **AudioRenderer** instance. This is because some operations can be performed only when the audio renderer is in a given state. If the application performs an operation when the audio renderer is not in the given state, the system may throw an exception or generate other undefined behavior.
**Figure 1** Audio renderer state
![](figures/audio-renderer-state.png)
### Asynchronous Operations
To ensure that the UI thread is not blocked, most **AudioRenderer** calls are asynchronous. Each API provides the callback and promise functions. The following examples use the promise functions. For more information, see [AudioRenderer in Audio Management](../reference/apis/js-apis-audio.md#audiorenderer8).
## How to Develop
1. Use **createAudioRenderer()** to create an **AudioRenderer** instance.
Set parameters of the audio renderer in **audioCapturerOptions**. This instance is used to render audio, control and obtain the rendering status, and register a callback for notification.
```js
var audioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_1,
......@@ -46,48 +49,15 @@ Here's an example of how to use AudioRenderer to play a raw audio file.
let audioRenderer = await audio.createAudioRenderer(audioRendererOptions);
```
2. Subscribe to audio interruption events using the **on** API.\
Stream-A is interrupted when Stream-B with a higher or equal priority requests to become active and use the output device.\
In some cases, the framework takes forced actions like pausing and ducking, and notifies the app using **InterruptEvent**. In other cases, the app can take action. In this situation, the app can choose to act on the **InterruptEvent** or ignore it. When the app is interrupted by forced action, it should handle the state, update the user interface, and so on.
In case of audio interrupts, the app may encounter write failures. Interrupt unaware apps can check the renderer state using the **audioRenderer.state** API before writing audio data, whereas interrupt aware apps will have more details accessible via this listener.\
<br/>
The following information will be provided by the Interrupt Event Notification:
1) **eventType:** Whether the interruption has begun or ended.
| Value | Description |
| :------------------- | :-------------------------------------------- |
| INTERRUPT_TYPE_BEGIN | Indicates that the interruption has started. |
| INTERRUPT_TYPE_END | Indicates that the interruption has finished. |
2) **forceType:** Whether the framework has already taken action or if the app is being suggested to take action.
2. Use **on('interrupt')** to subscribe to audio interruption events.
| Value | Description |
| :-------------- | :------------------------------------------------------------------ |
| INTERRUPT_FORCE | The audio state has been changed by the framework. |
| INTERRUPT_SHARE | The app can decide whether or not to respond to the InterruptEvent. |
Stream-A is interrupted when Stream-B with a higher or equal priority requests to become active and use the output device.
3) **hintType:** The kind of action taken or to be taken.
In some cases, the audio renderer performs forcible operations such as pausing and ducking, and notifies the application through **InterruptEvent**. In other cases, the application can choose to act on the **InterruptEvent** or ignore it.
| Value | Description |
| :-------------------- | :--------------------------- |
| INTERRUPT_HINT_PAUSE | Pausing the playback. |
| INTERRUPT_HINT_RESUME | Resuming the playback. |
| INTERRUPT_HINT_STOP | Stopping the playback. |
| INTERRUPT_HINT_DUCK | Ducking the stream volume. |
| INTERRUPT_HINT_UNDUCK | Unducking the stream volume. |
In the case of audio interruption, the application may encounter write failures. To avoid such failures, interruption unaware applications can use **audioRenderer.state** to check the renderer state before writing audio data. The applications can obtain more details by subscribing to the audio interruption events. For details, see [InterruptEvent](../reference/apis/js-apis-audio.md#interruptevent9).
4) **Some actions are exclusively forced or shared**, which means that they are performed by either the framework or the app.\
For instance, when a call is received while a music stream is ongoing, the framework forces the music stream to pause. When the call is finished, the framework will not forcibly resume the music stream. Instead, it will alert the app to resume the playback.
| Action | Description |
| :-------------------- | :-------------------------------------------------------------------------------- |
| INTERRUPT_HINT_RESUME | INTERRUPT_SHARE is always the forceType. It can only be done by the app. |
| INTERRUPT_HINT_DUCK | INTERRUPT_FORCE is always the forceType. It will always be done by the framework. |
| INTERRUPT_HINT_UNDUCK | INTERRUPT_FORCE is always the forceType. It will always be done by the framework. |
```
```js
audioRenderer.on('interrupt', (interruptEvent) => {
console.info('InterruptEvent Received');
console.info('InterruptType: ' + interruptEvent.eventType);
......@@ -133,12 +103,14 @@ Here's an example of how to use AudioRenderer to play a raw audio file.
});
```
4. Call the **start()** function on the AudioRenderer instance to start/resume the playback task.\
The renderer state will be STATE_RUNNING once the start is complete. You can then begin writing buffers.
```
3. Use **start()** to start audio rendering.
The renderer state will be **STATE_RUNNING** once the audio renderer is started. The application can then begin reading buffers.
```js
async function startRenderer() {
var state = audioRenderer.state;
// state should be prepared, paused or stopped.
// The state should be prepared, paused, or stopped.
if (state != audio.AudioState.STATE_PREPARED || state != audio.AudioState.STATE_PAUSED ||
state != audio.AudioState.STATE_STOPPED) {
console.info('Renderer is not in a correct state to start');
......@@ -154,11 +126,13 @@ Here's an example of how to use AudioRenderer to play a raw audio file.
console.error('Renderer start failed');
}
}
```
5. Make **write** calls to start rendering the buffers.
Read the audio data to be played into a buffer. Call the write function repeatedly to write data.
```
4. Call **write()** to write data to the buffer.
Read the audio data to be played to the buffer. Call **write()** repeatedly to write the data to the buffer.
```js
async function writeBuffer(buf) {
var state = audioRenderer.state;
if (state != audio.AudioState.STATE_RUNNING) {
......@@ -201,8 +175,9 @@ Here's an example of how to use AudioRenderer to play a raw audio file.
} , 30); // interval to be set based on audio file format
```
6. (Optional) Call the **pause()** or **stop()** function on the AudioRenderer instance.
```
5. (Optional) Call **pause()** or **stop()** to pause or stop rendering.
```js
async function pauseRenderer() {
var state = audioRenderer.state;
if (state != audio.AudioState.STATE_RUNNING) {
......@@ -235,12 +210,14 @@ Here's an example of how to use AudioRenderer to play a raw audio file.
} else {
console.error('Renderer stop failed');
}
}
```
}
```
7. After the playback task is complete, call the **release()** function on the AudioRenderer instance to release resources.\
AudioRenderer can use a lot of system resources. As a result, whenever the resources are no longer required, they must be released. To ensure that any system resources allocated to it are appropriately released, you should always call **release()**.
```
6. After the task is complete, call **release()** to release related resources.
**AudioRenderer** uses a large number of system resources. Therefore, ensure that the resources are released after the task is complete.
```js
async function releaseRenderer() {
if (state_ == RELEASED || state_ == NEW) {
console.info('Resourced already released');
......@@ -257,18 +234,6 @@ Here's an example of how to use AudioRenderer to play a raw audio file.
}
}
```
## **Importance of State Check:**
You should also keep in mind that an AudioRenderer is state-based.
That is, the AudioRenderer has an internal state that you must always check when calling playback control APIs, because some operations are only acceptable while the renderer is in a given state.\
The system may throw an error/exception or generate other undefined behaviour if you perform an operation while in the improper state.\
```
## **Asynchronous Operations:**
Most of the AudioRenderer calls are asynchronous. As a result, the UI thread will not be blocked.\
For each API, the framework provides both callback and promises functions.\
In the example, promise functions are used for simplicity. [AudioRender in the Audio API](../reference/apis/js-apis-audio.md#audiorenderer8)
provides reference for both callback and promise.
## **Other APIs:**
See [Audio](../reference/apis/js-apis-audio.md) for more useful APIs like getAudioTime, drain, and getBufferSize.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册