日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Sound recording and encoding in MP3 format.

發(fā)布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Sound recording and encoding in MP3 format. 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • Download source files - 18.7 Kb
  • Download demo project - 185 Kb

Introduction

Have you ever tried to write something for recording sound from the sound card and encoding it in MP3 format? Not interesting? Well, to make stuff more interesting, have you ever tried to write an MP3 streaming, internet radio sever? I know, you'll say "What for? There are good and pretty much standard implementations like Icecast or SHOUcast". But, anyway, have you ever tried, at least, to dig a bit inside this entire kitchen or write anything similar for your soul? Well, that's what this article is about. Of course, we won't manage to cover all topics in one article; at the end, this may be tiresome. So, I will split the entire topic in a few articles, this one covering the recording and encoding process.

Background

Obviously, the first problem everyone encounters is the MP3 encoding itself. Trying to write something that will work properly isn't quite an easy task. So, I won't go too far and will stop at the LAME (Sourceforge) encoder, considered one of the best (one, not the only!). I am using version 3.97); those interested in having sources, feel free to download them from SourceForge (it's an open source project). The relevant "lame_enc.dll" is also included in the demo project (see the?links at the top of this article).

The next problem is recording the sound from the soundcard. Well, with some luck, on Google, MSDN, and CodeProject, you can find many articles related to this topic. I should say that I am using the?low level waveform-audio API (see the Windows Media Platform SDK, e.g., waveInOpen(...), mixerOpen(...), etc.).

So, let's go with the details now.

MP3 Encoding

Download the "mp3_stream_src.zip" file containing the sources (see the link to the sources at the top of this article). Inside it, you should find the?"mp3_simple.h" file (see the?INCLUDE folder after un-zipping). It contains the definition and implementation of the CMP3Simple class. This class is a wrapper of the LAME API, which I tried to design to make life a bit easier. I commented code as much as possible, and I hope those?comments are good enough. All we need to know at this point:

  • When instantiating a CMP3Simple object, we need to define the desired bitrate at what to encode the sound's samples, expected frequency of the sound's samples, and (if necessary to re-sample) the desired frequency of the encoded sound: // Constructor of the class accepts only three parameters. // Feel free to add more constructors with different parameters, // if a better customization is necessary. // // nBitRate - says at what bitrate to encode the raw (PCM) sound // (e.g. 16, 32, 40, 48, ... 64, ... 96, ... 128, etc), see // official LAME documentation for accepted values. // // nInputSampleRate - expected input frequency of the raw (PCM) sound // (e.g. 44100, 32000, 22500, etc), see official LAME documentation // for accepted values. // // nOutSampleRate - requested frequency for the encoded/output // (MP3) sound. If equal with zero, then sound is not // re-sampled (nOutSampleRate = nInputSampleRate). CMP3Simple(unsigned int nBitRate, unsigned int nInputSampleRate = 44100,unsigned int nOutSampleRate = 0);
  • Encoding itself is performed via CMP3Simple::Encode(...). // This method performs encoding. // // pSamples - pointer to the buffer containing raw (PCM) sound to be // encoded. Mind that buffer must be an array of SHORT (16 bits PCM stereo // sound, for mono 8 bits PCM sound better to double every byte to obtain // 16 bits). // // nSamples - number of elements in "pSamples" (SHORT). Not to be confused // with buffer size which represents (usually) volume in bytes. See // also "MaxInBufferSize" method. // // pOutput - pointer to the buffer that will receive encoded (MP3) sound, // here we have bytes already. LAME says that if pOutput is not // cleaned before call, data in pOutput will be mixed with incoming // data from pSamples. // // pdwOutput - pointer to a variable that will receive the // number of bytes written to "pOutput". See also "MaxOutBufferSize" // method. BE_ERR Encode(PSHORT pSamples, DWORD nSamples, PBYTE pOutput, PDWORD pdwOutput);
  • Recording from the soundcard

    Similarly, after un-zipping the?"mp3_stream_src.zip" file, inside the?INCLUDE folder, you should find the "waveIN_simple.h" file. It contains the definitions and implementations for the?CWaveINSimple, CMixer and CMixerLine classes. Those classes are wrappers for a sub-set of the waveform-audio API functions. Why just a sub-set? Because (I am lazy sometimes), they encapsulate only functionality associated with Wave In devices (recording). So, Wave Out devices (playback) are not captured (type "sndvol32 /r" from "Start->Run" to see what I mean). Check comments I added to each class to have a better picture of what they are doing. What we need to know at this point:

  • One CWaveINSimple device has one CMixer which has zero or more CMixerLines.
  • Constructors and destructors of all those classes are declared "private" (due design).
    • Objects of the?CWaveINSimple class can not be instantiated directly, for that the?CWaveINSimple::GetDevices() and CWaveINSimple::GetDevice(...) static methods are declared.
    • Objects of the?CMixer class can not be instantiated directly, for that the?CWaveINSimple::OpenMixer() method is declared.
    • Objects of the?CMixerLine class can not be instantiated directly, for that the?CMixer::GetLines() and CMixer::GetLine(...) methods are declared.
    • In order to capture and process further sound data, a class must inherit from the IReceiver abstract class and implement the IReceiver::ReceiveBuffer(...) method. Further, an instance of the IReceiver derivate is passed to CWaveINSimple via CWaveINSimple::Start(IReceiver *pReceiver).
    • // See CWaveINSimple::Start(IReceiver *pReceiver) below. // Instances of any class extending "IReceiver" will be able // to receive raw (PCM) sound from an instance of the CWaveINSimple // and process sound via own implementation of the "ReceiveBuffer" method. class IReceiver { public:virtual void ReceiveBuffer(LPSTR lpData, DWORD dwBytesRecorded) = 0; }; ... class CWaveINSimple { private: ...// This method starts recording sound from the // WaveIN device. Passed object (derivate from // IReceiver) will be responsible for further // processing of the sound data. void _Start(IReceiver *pReceiver); ... public: ...// Wrapper of the _Start() method, for the multithreading // version. This is the actual starter. void Start(IReceiver *pReceiver); ... };

      Let's see some examples.

      Examples

    • How would we list all the Wave In devices in the system? const vector<CWaveINSimple*>& wInDevices = CWaveINSimple::GetDevices(); UINT i;for (i = 0; i < wInDevices.size(); i++) {printf("%s/n", wInDevices[i]->GetName()); }
    • How would we list a Wave In device's lines (supposing that strDeviceName = e.g., "SoundMAX Digital Audio")? CWaveINSimple& WaveInDevice = CWaveINSimple::GetDevice(strDeviceName); CHAR szName[MIXER_LONG_NAME_CHARS]; UINT j;try {CMixer& mixer = WaveInDevice.OpenMixer();const vector<CMixerLine*>& mLines = mixer.GetLines();for (j = 0; j < mLines.size(); j++) {// Useful when Line has non proper English name ::CharToOem(mLines[j]->GetName(), szName);printf("%s/n", szName);}mixer.Close(); } catch (const char *err) {printf("%s/n",err); }
    • How would we record and encode in MP3 actually?

      First of all, we define a class like:

      class mp3Writer: public IReceiver { private:CMP3Simple m_mp3Enc;FILE *f;public:mp3Writer(unsigned int bitrate = 128, unsigned int finalSimpleRate = 0): m_mp3Enc(bitrate, 44100, finalSimpleRate) {f = fopen("music.mp3", "wb");if (f == NULL) throw "Can't create MP3 file.";};~mp3Writer() {fclose(f);};virtual void ReceiveBuffer(LPSTR lpData, DWORD dwBytesRecorded) {BYTE mp3Out[44100 * 4];DWORD dwOut;m_mp3Enc.Encode((PSHORT) lpData, dwBytesRecorded/2, mp3Out, &dwOut);fwrite(mp3Out, dwOut, 1, f);}; };

      and (supposing that strLineName = e.g., "Microphone"):

      try {CWaveINSimple& device = CWaveINSimple::GetDevice(strDeviceName);CMixer& mixer = device.OpenMixer();CMixerLine& mixerline = mixer.GetLine(strLineName);mixerline.UnMute();mixerline.SetVolume(0);mixerline.Select();mixer.Close();mp3Writer *mp3Wr = new mp3Writer();device.Start((IReceiver *) mp3Wr);while( !_kbhit() ) ::Sleep(100);device.Stop();delete mp3Wr; } catch (const char *err) {printf("%s/n",err); }CWaveINSimple::CleanUp();
    • Remark 1

      mixerline.SetVolume(0) is a pretty tricky point. For some sound cards,?SetVolume(0) gives original (good) sound's quality, for others, SetVolume(100) does the same. However, you can find sound cards where SetVolume(15) is the best quality. I have no good advices here, just try and check.

      Remark 2

      Almost every sound card supports "Wave Out Mix" or "Stereo Mix" (the list is extensible) Mixer's Line. Recording from such a line (mixerline.Select()) will actually record everything going to the sound card's Wave Out (read "speakers"). So, leave WinAmp or Windows Media Player to play for a while, and start the application to record the sound at the same time, you'll see the result.

      Remark 3

      Rather than calling:

      mp3Writer *mp3Wr = new mp3Writer();

      it is also possible to instantiate an instance of the mp3Writer as following (see the class definition above):

      mp3Writer *mp3Wr = new mp3Writer(64, 32000);

      This will produce a final MP3 at a 64 Kbps bitrate and 32 Khz sample rate.

      Comments on using the demo application

      The demo application (see the links at the top of this article) is a console application supporting two command line options. Executing the application without specifying any of the command line options will simply print the usage guideline, e.g.:

      ...>mp3_stream.exe mp3_stream.exe -devicesWill list WaveIN devices.mp3_stream.exe -device=<device_name>Will list recording lines of the WaveIN <device_name> device.mp3_stream.exe -device=<device_name> -line=<line_name> [-v=<volume>] [-br=<bitrate>] [-sr=<samplerate>]Will record from the <line_name> at the given voice <volume>, output <bitrate> (in Kbps)and output <samplerate> (in Hz).<volume>, <bitrate> and <samplerate> are optional parameters.<volume> - integer value between (0..100), defaults to 0 if not set.<bitrate> - integer value (16, 24, 32, .., 64, etc.), defaults to 128 if not set.<samplerate> - integer value (44100, 32000, 22050, etc.), defaults to 44100 if not set.

      Executing the application with the "-devices" command line option will print the names of the Wave In devices currently installed in the system, e.g.:

      ...>mp3_stream.exe -devices Realtek AC97 Audio

      Executing the?application with the "-device=<device_name>" command line option will list all the lines of the selected Wave In device, e.g.:

      ...>mp3_stream.exe "-device=Realtek AC97 Audio" Mono Mix Stereo Mix Aux TV Tuner Audio CD Player Line In Microphone Phone Line

      At the end, the application will start recording (and encoding) sound from the selected Wave In device/line (microphone in this example) when executing with the following command line options:

      ...>mp3_stream.exe "-device=Realtek AC97 Audio" -line=MicrophoneRecording at 128Kbps, 44100Hz from Microphone (Realtek AC97 Audio). Volume 0%.hit <ENTER> to stop ...

      Recorded and encoded sound is saved in the "music.mp3" file, in the same folder from where you executed the application.

      If you want to record sound that is currently playing (e.g., AVI movie, or Video DVD, or ...) through the soundcard Wave Out, you can run the application with the following options:

      ...>mp3_stream.exe "-device=Realtek AC97 Audio" "-line=Stereo Mix"

      However, this may be specific for my configuration only (also explained in the "Remark 2" above).

      You can specify additional command line parameters, e.g.:

      ...>mp3_stream.exe "-device=Realtek AC97 Audio" "-line=Stereo Mix" -v=100 -br=32 -sr=32000

      This will set the line’s volume at 100%, and will produce the final MP3 at 32 Kbps and 32 Khz.

      Conclusion

      In this article, I covered couple of months I spent investigating MP3 encoding APIs and recording (capturing actually) sound going to the sound card's speakers. I used all this techniques for implementing an internet based radio station (MP3 streaming server). I found this topic very interesting, and decided to share some of my code. In one of my next articles, I will try to cover some of the aspects related to MP3 streaming and IO Completion Ports, but, until that time, I have to clean existing code, comment it, and prepare the article :).

    • License

      This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

      A list of licenses authors might use can be found here

      ?

    總結(jié)

    以上是生活随笔為你收集整理的Sound recording and encoding in MP3 format.的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 美女扒开腿让男生捅 | 亚洲美女性视频 | 色狠狠一区二区 | 欧美超碰在线观看 | 天天干天天操天天射 | 加勒比一区二区三区 | 黑人巨茎大战欧美白妇 | 黑人干亚洲| 久草视频网| 亚洲天堂网一区 | 亚洲av日韩av永久无码下载 | 久久久久久久久久久网 | 在线看国产视频 | 捆绑调教sm束缚网站 | 视频精品久久 | 青娱乐国产在线 | 91se在线 | 男裸体无遮挡网站 | 中文字幕一区二区三区门四区五区 | 一级片在线观看免费 | 亚洲一区二区影视 | 成人黄页网站 | 日本免费黄色大片 | 亚洲午夜精品在线 | 黄色影音 | 朝桐光av在线一区二区三区 | 免费av网站大全 | 一区精品视频在线观看 | www.插插 | av影视在线观看 | 天堂中文在线视频 | 娇妻被肉到高潮流白浆 | 久久久久久久久久久av | 久久国产乱子伦精品 | 中国女人高潮hd | 男生插女生视频在线观看 | 青青草久久爱 | 国产一区二区三区中文字幕 | 91视频在线观看网站 | 国产成人精品亚洲精品色欲 | 亚洲成人乱码 | 日本高清网色 | 免费av看| 久久白浆 | 毛茸茸成熟亚洲人 | 国产男女自拍 | a天堂视频| 91色交视频 | 五月天欧美 | 亚洲欧美日韩久久精品 | 国内偷拍av | 少妇高清精品毛片在线视频 | 国产高潮在线观看 | 久热网 | 黄色片网站视频 | 午夜色av | 中文字幕日韩电影 | 国产一区在线视频观看 | 特级特黄aaaa免费看 | 高h视频在线观看 | 91福利区 | 在线观看日本一区 | 国产精品无码久久久久久电影 | 日本一区二区高清不卡 | 国产精品久久77777 | 日产精品久久久久 | 精品视频91 | 日本一区二区三区四区在线观看 | 自拍色图| 少妇福利视频 | 亚洲精品毛片av | 欧美巨大荫蒂茸毛毛人妖 | 久久香蕉热 | 韩国三级hd中文字幕的背景音乐 | 亚洲巨乳在线 | 久久久久久久久久久久久av | 蜜桃视频一区二区在线观看 | 美女操操操 | 草色噜噜噜av在线观看香蕉 | 国产乱大交 | 小毛片网站 | 中文字幕免费在线观看 | 伊人春色在线视频 | 国产寡妇亲子伦一区二区三区四区 | 狠狠操天天干 | 手机在线中文字幕 | 激情av网站| 日p视频在线观看 | 欧美激情在线免费 | 欧美性猛交乱大交 | 久久亚洲免费视频 | 日本不卡视频 | 在线黄色免费 | 美女131爽爽爽 | 午夜视频成人 | 久久久一级片 | 北条麻妃青青久久 | 97视频在线观看免费高清完整版在线观看 | 国产精品视频第一页 |