In nature, sound is very complex, and waveforms are extremely complex. We usually use pulse code modulation coding. That is, PCM encoding. PCM converts a continuously changing analog signal into a digital code by sampling, quantization, and encoding. Sampling: sampling rate is called in audio collection. Because sound is actually an energy wave, there are also frequency and amplitude features, frequency corresponds to the time axis, amplitude corresponds to the level axis. The wave is infinitely smooth, and the string line can be regarded as composed of countless points. Because the storage space is relatively limited, the point of the string line must be sampled during the digital encoding process. The sampling process is to extract the frequency value of a certain point. Obviously, the more points are extracted in one second, the richer the frequency information is obtained. In order to restore the waveform, there must be two sampling points, and the highest frequency that the ears can feel is 20 kHz. Therefore, to meet the auditory requirements of the ears, at least 40 kb of sampling per second is required and expressed at 40 kHz, this 40 kHz is the sampling rate. Our common CD, sampling rate is 44.1 kHz. Quantization: here the sampling size is the quantization process, which quantifies the energy value of the frequency to indicate the signal strength. The Quantization level is an integer power of 2. We usually use 16-bit CD sampling size, that is, the 16 power of 2. Encoding: According to the sampling rate and sampling size, we can know that, compared with natural signals, audio encoding can only be infinitely close, at least the current technology can only do this, relative to natural signals, any digital audio encoding scheme is lossy because it cannot be completely restored. In computer applications, PCM encoding can achieve the highest fidelity. It is widely used for material storage and music appreciation. CD, DVD, and common wav files are all used. Therefore, PCM is about lossless encoding, because PCM represents the best fidelity level in digital audio, does not mean that PCM can ensure absolute fidelity of the signal, PCM can only achieve the maximum infinite proximity. We habitually include MP3 in the lossy Audio Encoding category, which is relative to PCM encoding. The purpose of emphasizing the relative lossy and lossless nature of coding is to tell everyone that it is difficult to achieve true lossless, just like using numbers to express the circumference rate, no matter how high the accuracy is, it is just infinitely close, not the value that truly equals the circumference Rate Why audio compression technology? It is easy to calculate the bit rate of a pcm audio stream. The sampling rate value × the sample size Value × the number of audio channels bps. A pcm-encoded WAV file with a sampling rate of 44.1 kHz and a sampling size of 16 bit. The data rate is 44.1k × 16 × 2 = 1411.2 kbps. We often say that the 1411.2 kb MP3 file corresponds to the wav parameter, which is kbps. this parameter is also called data bandwidth, and it is a concept of bandwidth in ADSL. Divide the bitrate by 8 to get the data rate of this wav, that is, 176.4kb/s. This indicates that the sampling rate for one second is 44.1 kHz, the sampling size is 16 bit, And the PCM-encoded audio signal in two channels requires a space of 176.4kb, which is about 10.34 m in 1 minute, this is unacceptable for most users, especially those who like to listen to music on their computers. To reduce disk usage, there are only two ways to reduce sampling metrics or compression. Reducing indicators is not desirable, so experts have developed various compression solutions. The purpose is different from the target market. The audio compression encoding quality and compression ratio are different. We will refer to them in the following articles. One thing is certain, they are all compressed.
Relationship between frequency and Sampling Rate The sampling rate indicates the number of times the original signal is sampled per second. The common audio file sampling rate is 44.1 KHz. What does this mean? Assume that we have two sine wave signals, 20Hz and 20 KHz respectively, with a length of one second, corresponding to the lowest frequency and the highest frequency we can hear, what kind of result can we obtain when we sample the two signals at 40 kHz? The result is that the 20Hz signal is sampled for 40 KB/20 = 2000 times each time, while the 20 KB signal is only sampled twice each time. Obviously, At the same sampling rate, the information of low frequency is far more detailed than that of high frequency. This is also the reason why some audio enthusiasts accuse the CD of having insufficient digital sound. The 44.1KHz sampling of the CD cannot ensure that the high-frequency signal is well recorded. To better record high-frequency signals, it seems that a higher sampling rate is required, so some friends use a 48 KHz sampling rate when capturing the CD audio. This is not desirable! In fact, this does not have any benefits for sound quality. For rail capture software, maintaining the same sampling rate as the 44.1KHz provided by CD is one of the best quality assurance, rather than improving it. A high sampling rate is useful only when it is relative to a simulated signal. If the sampled signal is digital, do not try to increase the sampling rate.
Stream features With the development of the network, people have put forward requirements for online music listening. Therefore, they also require that audio files can be read and played simultaneously, instead of reading all the files and then playing back them, in this way, you can achieve listening without downloading. It is also possible to play videos while encoding. This feature enables online live broadcast and sets up your own digital broadcast stations. 2. Description of Audio Acquisition Parameters Using AudioRecord in android In android, the api for collecting audio is android. media. AudioRecord.Several parameters of the constructor are standard sound collection parameters. The meanings of parameters are as follows: Public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
Since:API level 3
Class constructor. Parameters
Audiosource |
The recording source. SeeMediaRecorder. AudioSourceFor recording source definitions. Audio Source: Where to collect audio. Here we certainly collect audio from the microphone, so the value of this parameter is mic |
Samplerateinhz |
The sample rate expressed in hertz. Examples of rates are (but not limited to) 44100,220 50 and 11025. Sampling Rate: the sampling frequency of the audio. The number of samples per second. The higher the sampling rate, the higher the sound quality. The instances provided are 44100, 22050, 11025, but are not limited to these parameters. For example, low sampling rates such as 4000 and 8000 can be used to collect low-quality audio. |
Channelconfig |
Describes the configuration of the audio channels. See CHANNEL_IN_MONOAnd CHANNEL_IN_STEREO Sound channel settings: Android supports dual-channel stereo and single-channel. Mono single channel, stereo |
Audioformat |
The format in which the audio data is represented. See ENCODING_PCM_16BITAnd ENCODING_PCM_8BIT Encoding standard and sampling size: Of course, the collected data uses PCM encoding (pulse code modulation encoding, that is, PCM encoding. PCM converts a continuously changing analog signal to a digital code by sampling, quantization, and encoding .) Sample size supported by android: 16 Bit Or 8bit. Of course, the larger the sampling size, the more information, the higher the sound quality. Now the mainstream sampling size is 16 bit, 8 bit for low-quality voice transmission. Enough. |
BufferSizeInBytes |
The total size (in bytes) of the buffer where audio data is written to during the recording. New audio data can be read from this buffer in smaller chunks than this size. See GetMinBufferSize (int, int, int)To determine the minimum required buffer size for the successful creation of an AudioRecord instance. Using values smaller than getMinBufferSize () will Result in an initialization failure. The size of the buffer required for data collection. If you do not know the minimum size, you can view it in getMinBufferSize. |
The collected data is stored in a byteBuffer and can be read using a stream. It can also be saved as a file 3. Android uses AudioRecord recording-related and audio file EncapsulationMediaRecord can be used for recording in Android, which is easy to operate. However, it is not professional enough to Process audio. If you want to process audio in real time or encapsulate the audio You can use audiorecord for recording. Here is a piece of code. Audio Recording in audiorecord and audio encapsulation in WAV format are implemented. Audiotrack and audiotrack can be used for edge recording and play, you can refer to: http://blog.sina.com.cn/s/blog_6309e1ed0100j1rw.html The code here is not played. But there are encapsulation and details, as follows: Package com. ppmeet; import java. io. file; import java. io. fileInputStream; import java. io. fileNotFoundException; import java. io. fileOutputStream; import java. io. IOException; import android. app. activity; import android. graphics. pixelFormat; import android. media. audioFormat; import android. media. audioRecord; import android. media. mediaRecorder; import android. OS. bundle; import android. view. view; import android. view. View. onClickListener; import android. view. window; import android. view. windowManager; import android. widget. button;/*** class name: TestAudioRecord <BR> * class description: Use AudioRecord for recording <BR> * PS: <BR> ** @ version 1.00 2011/09/21 * @ author CODYY) peijiangping */public class TestAudioRecord extends Activity {// audio retrieval source private int audioSource = MediaRecorder. audioSource. MIC; // sets the audio sampling rate. 44100 is the current standard, but some settings The backup still supports 11025, 44100, private static int sampleRateInHz =; // set the audio recording channel CHANNEL_IN_STEREO to dual-channel, and CHANNEL_CONFIGURATION_MONO to single-channel private static int channelConfig = AudioFormat. CHANNEL_IN_STEREO; // Audio Data Format: PCM 16-bit each sample. Ensure device support. PCM 8-bit each sample. Not necessarily supported by devices. Private static int audioFormat = AudioFormat. ENCODING_PCM_16BIT; // buffer byte size private int bufferSizeInBytes = 0; private Button Start; private Button Stop; private AudioRecord audioRecord; private boolean isRecord = false; // set the recording status. // AudioName specifies the private static final String AudioName = "/sdcard/love. raw "; // NewAudioName private static final String NewAudioName ="/sdcard/new.wav "; public void onC Reate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); getWindow (). setFormat (PixelFormat. TRANSLUCENT); // enables the requestWindowFeature (Window. FEATURE_NO_TITLE); // remove the interface title getWindow (). setFlags (WindowManager. layoutParams. FLAG_FULLSCREEN, WindowManager. layoutParams. FLAG_FULLSCREEN); // reset the page size setContentView (R. layout. main); init ();} private void init () {Start = (Button) this. findViewById (R. id. sta Rt); Stop = (Button) this. findViewById (R. id. stop); Start. setOnClickListener (new TestAudioListener (); Stop. setOnClickListener (new TestAudioListener (); creatAudioRecord ();} private void creatAudioRecord () {// obtain the buffer byte size bufferSizeInBytes = AudioRecord. getMinBufferSize (sampleRateInHz, channelConfig, audioFormat); // create the AudioRecord object audioRecord = new AudioRecord (audioSource, sampleRateInHz, channelConfig, audi OFormat, bufferSizeInBytes);} class TestAudioListener implements OnClickListener {@ Overridepublic void onClick (View v) {if (v = Start) {startRecord ();} if (v = Stop) {stopRecord () ;}} private void startRecord () {audioRecord. startRecording (); // set the recording status to trueisRecord = true; // enable the audio file writing Thread new Thread (new AudioRecordThread ()). start ();} private void stopRecord () {close ();} private void close () {if (audioRecord! = Null) {System. out. println ("stopRecord"); isRecord = false; // stop writing files to audioRecord. stop (); audioRecord. release (); // release resource audioRecord = null;} class AudioRecordThread implements Runnable {@ Overridepublic void run () {writeDateTOFile (); // write the raw data copyWaveFile (AudioName, NewAudioName) to the file; // Add the header file to the raw data}/*** write the data to the file, but it cannot be played, because the audio obtained by AudioRecord is RAW Raw raw audio, * if you need to play the audio, you must add some format or encoding header information. However, the advantage is that you can process the raw audio data. For example, you need to make a talking TOM * Cat to process the audio here, then re-encapsulate the audio. Therefore, it is easier to process the audio. */Private void writeDateTOFile () {// a new byte array is used to store some bytes of data. The size is the buffer size byte [] audiodata = new byte [bufferSizeInBytes]; FileOutputStream fos = null; int readsize = 0; try {File file = new File (AudioName); if (file. exists () {file. delete ();} fos = new FileOutputStream (file); // create an accessable Byte file} catch (Exception e) {e. printStackTrace ();} while (isRecord = true) {readsize = audioRecord. read (audiodata, 0, bufferSize InBytes); if (AudioRecord. ERROR_INVALID_OPERATION! = Readsize) {try {fos. write (audiodata);} catch (IOException e) {e. printStackTrace () ;}}try {fos. close (); // close the write stream} catch (IOException e) {e. printStackTrace () ;}// obtain the private void copyWaveFile (String inFilename, String outFilename) of the audio file that can be played. {FileInputStream in = null; FileOutputStream out = null; long totalAudioLen = 0; long totalDataLen = totalAudioLen + 36; long longSampleRate = sampleRateInHz; int chan Nels = 2; long byteRate = 16 * sampleRateInHz * channels/8; byte [] data = new byte [bufferSizeInBytes]; try {in = new FileInputStream (inFilename ); out = new FileOutputStream (outFilename); totalAudioLen = in. getChannel (). size (); totalDataLen = totalAudioLen + 36; WriteWaveFileHeader (out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); while (in. read (data )! =-1) {out. write (data);} in. close (); out. close ();} catch (FileNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace () ;}}/*** a header is provided here. Insert this information to obtain the files that can be played. * This Is Why I inserted these 44 bytes. I haven't studied it in depth. However, if you open a wav * audio file, you can find that the header file is basically the same. Files in each format have * their own header files. */Private void WriteWaveFileHeader (FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) throws IOException {byte [] header = new byte [44]; header [0] = 'R'; // RIFF/WAVE headerheader [1] = 'I'; header [2] = 'F '; header [3] = 'F'; header [4] = (byte) (totalDataLen & 0xff); header [5] = (byte) (totalDataLen> 8) & 0xff); header [6] = (byte) (totalDataLen> 16) & 0xff); header [7] = (byte) (totalDataLen> 24) & 0xff); header [8] = 'W'; header [9] = 'a'; header [10] = 'V'; header [11] = 'E '; header [12] = 'F'; // 'fmt' chunkheader [13] = 'M'; header [14] = 'T'; header [15] = ''; header [16] = 16; // 4 bytes: size of 'fmt' chunkheader [17] = 0; header [18] = 0; header [19] = 0; header [20] = 1; // format = 1 header [21] = 0; header [22] = (byte) channels; header [23] = 0; header [24] = (byte) (longSampleRate & 0xff); header [25] = (byte) (longSampleRate> 8) & 0xff ); header [26] = (byte) (longSampleRate> 16) & 0xff); header [27] = (byte) (longSampleRate> 24) & 0xff ); header [28] = (byte) (byteRate & 0xff); header [29] = (byte) (byteRate> 8) & 0xff ); header [30] = (byte) (byteRate> 16) & 0xff); header [31] = (byte) (byteRate> 24) & 0xff ); header [32] = (byte) (2*16/8); // block alignheader [33] = 0; header [34] = 16; // bits per sampleheader [35] = 0; header [36] = 'D'; header [37] = 'a'; header [38] = 'T '; header [39] = 'a'; header [40] = (byte) (totalAudioLen & 0xff); header [41] = (byte) (totalAudioLen> 8) & 0xff); header [42] = (byte) (totalAudioLen> 16) & 0xff); header [43] = (byte) (totalAudioLen> 24) & 0xff); out. write (header, 0, 44) ;}@ Overrideprotected void onDestroy () {close (); super. onDestroy ();}} |