【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 3556|回复: 3

[原创]FROM ZERO TO Vorbis (从零开始学Vorbis )--解开Ogg编程

[复制链接]
发表于 2006-10-24 16:39:17 | 显示全部楼层 |阅读模式

以下翻译如有不当请指正

It all starts by installing the libraries. On the CD you'll find several Ogg Vorbis ZIP files (in the Goodies folder). The following list shows you how to install those files. (I included everything on the CD if you're curious, but the only two files you need for this chapter are libvorbis-1.0.zip and OggVorbis-win32sdk-1.0.zip.)

这段就不用翻译了,说的是在CD上可以找到libvorbis-1.0.zip 和 OggVorbis-win32sdk-1.0.zip。大家没有CD 就在网上搜一搜吧,现在的版本比这个高,到OGG官方网站去下载好了(http://www.vorbis.com/)。

The goal is to put all of the files from both zip files into one directory tree. So, you need to unzip each file into a separate directory (making sure to maintain the directory structure stored inside the zip file), and then copy the contents of each directory into one main directory (it's safe to overwrite files).

老外说话真不利索:这2个压缩包现分别解压缩在各自单独的文件夹里,然后把这两个解压的文件一起拷贝到一个统一的目录下。

Either way, you should end up with a tree that contains include, lib, and win32 examples, and a whole bunch of other folders. In particular, make sure that you have both an ogg folder and a vorbis folder inside your include folder.

这样那,你就得到了一个包含include ,lib ,win32 examples的一个完整的目录。并且你要把ogg 文件夹和vorbis 文件夹放在include 里面。

  1. 1.Start a command shell (Go start, run, then type cmd on Windows NT, 2000, or XP, or command on Windows 95, 98, and Me).
    打开开始菜单,WIN2000以上的操作系统在运行里面输入CMD ,98以下的打开DOS输入窗口。

  2. 2.You need to set an environment variable called SRCROOT. To properly install the libraries, SRCROOT must point to the top-level folder where you unzipped the files. For example, if you copied both folders into a single folder called C:\libraries\oggvorbis, then at the command prompt you should type set SRCROOT=Clibraries\oggvorbis. I'd highly recommend making sure that there are no spaces in the your install path, since then you won't have to deal with quoting this path.
    你需要设置variable被叫做SRCROOT 的运行环境,来完全安装文件库,SRCROOT必须指向你刚才解压的文件目录,比如你把文件解压在C:\libraries\oggvorbis里,那么你就要输入类似于set RCROOT=Clibraries\oggvorbis这样的命令。

  3. 3.Type cd %SRCROOT%\win32. If you've set your SRCROOT environment variable correctly, you should end up in the win32 folder, C:\libraries\oggvorbis\win32.
    输入 cd %SRCROOT%\win32 如果你刚才环境配置的输入是正确地,那么你就会进入C:\libraries\oggvorbis\win32
    (译者鼯鼠注*:没这么麻烦吧,我的使用和普通SDK使用方法一样,只要在VC中把Lib和Include文件夹设置好就可以运行了,这位外国友人这么麻烦的设置也许有他的道理吧)

  4. 4.Inside this folder are batch files that build all of the different Ogg and Vorbis libraries. If you want to, you can run each batch file, but the only ones you need to run right now are build_vorbis_static.bat, build_vorbis_static_debug.bat, build_vorbisfile_static.bat, and build_vorbisfile_static_debug.bat. These batch files will create vorbis_static.lib, vorbis_static_d.lib, vorbisfile_static.lib, and vorbisfile_static_d.lib, respectively. Note that you will get some warnings when you compile these.
    在这里面你能看到一些构造文件,如果你想做的话,你可以运行他们。build_vorbis_static.bat, build_vorbis_static_debug.bat, build_vorbisfile_static.bat, and build_vorbisfile_static_debug.bat这些bat文件就会帮你生成vorbis_static.lib, vorbis_static_d.lib, vorbisfile_static.lib, and vorbisfile_static_d.lib。注意你在编译他们的时候会遇到一些警告
    (译者鼯鼠注*:老实说,用VC有些根本就编译不过去)

[此贴子已经被作者于2006-10-25 8:50:39编辑过]
 楼主| 发表于 2006-10-24 16:45:44 | 显示全部楼层

The next step is to set up your DevStudio project to use the Ogg Vorbis libraries. If you want to add Ogg Vorbis to a project, you need to do a few things:

下来我们要设置我们的编辑器了,我们要做一下几步:

  1. You need to add the Ogg Vorbis include path to your project. To do this, select Settings from the Project menu, and go to the C/C++ Tab. Choose Preprocessor from the Category dropdown. In the Additional Include Directories edit box, type a relative path from your project to the include folder underneath where you installed Ogg Vorbis. For example, for this chapter's example program, I would enter ..\..\libvorbis-1.0\include.
    在你的项目属性中,C/C++ 里面选择预处理,在库文件这里增加一个..\..\libvorbis-1.0\include文件夹(译者鼯鼠注*编辑器不同设置地方不同,大家明白是在干什么就可以了),这样我们就设置好了Include目录。

  2. You need to link with the Ogg Vorbis libraries. To do this, go to the Link tab in the settings dialog, and select the Input category. In the edit box labeled Object/library modules, add the Ogg Vorbis libs you want to use. For this chapter's sample program, I've added vorbisfile_static.lib, ogg_static.lib, and vorbis_static.lib.
    连接器里面依赖项中增加vorbisfile_static.lib, ogg_static.lib, and vorbis_static.lib这几个库文件。

  3. You need to add the Ogg Vorbis library directory to your library path. In the same place, a couple of edit boxes below Object/library modules, is another edit box called Additional Library Path. Add the relative path to your Ogg Vorbis lib directory here. For the Ch8p1_OggVorbisPlayback sample program, this is ..\..\libvorbis-1.0\lib. Separate paths using commas.
    然后就不详细说了,设定好..\..\libvorbis-1.0\lib目录(译者鼯鼠注*不会的查看本论坛的DirectX 9 进阶手册

  4. In your code, make sure you include the right Ogg Vorbis headers, and make sure you use vorbis/ in their path. For example, if you wanted to include vorbisfile.h, you'd type #include <vorbis/vorbisfile.h>. The preprocessor tacks this onto the relative path you added in step 1, so you will end up with something like ..\..\libvorbis-1.0\include\vorbis\vorbisfile.h.
    在你的代码中添加调用Vorbis 的头文件,好比 #include <vorbis/vorbisfile.h>.

[此贴子已经被作者于2006-10-24 17:09:49编辑过]
 楼主| 发表于 2006-10-24 16:46:32 | 显示全部楼层

USING VORBIS

Hooray! If you're reading this, I'll assume you've successfully completed the most frustrating part of dealing with a third party API—installing and configuring the libraries. Now it's time to start looking at some Ogg Vorbis code.

Using the Vorbisfile API

The vorbisfile API is the simplest Ogg Vorbis API available. It allows you to easily read Ogg Vorbis files and convert them into uncompressed PCM streams. MSITStore:C:\Downloads\游戏音频程序设计-Beginning.Game.Audio.Programming\Beginning%20Game%20Audio%20Programming\Premier.Press.Beginning.Game.Audio.Programming.eBook-LiB.chm::/6916final/LiB0046.html#ch08fig01" target="_blank" >Figure 8.1 shows how to use the API. There are other APIs available (check out the Ogg Vorbis docs), but for this chapter you'll be using the Vorbisfile API exclusively.

The API is structured in such a way as to resemble the process of reading a normal file. To work with a normal file, you open it, read from it, and then close it when you're finished. Similarly, before you can do anything else with an Ogg Vorbis file, you have to open it using the ov_open API call. This call takes as input a handle to a file that you've already opened with fopen, and the address of a OggVorbis_File structure it should fill up.

Once you've opened an Ogg Vorbis file, you can do a few different things with it. You can get some information about it by calling the ov_info API function. This takes as input a pointer to an OggVorbis_File structure (the same one you got back from ov_open), and the address of a vorbis_info structure it should fill up. The vorbis_info structure, declared in vorbis/codec.h, contains the version of the file, the number of channels, its sample rate, and possibly its bit rate (depending on if the file's bit rate changes or not).

Other useful API functions include ov_pcm_total, which, if it can, gives you the total number of samples, and ov_comment, which gives you the user comments in the file (artist, album, title, and so on).

However, the most useful API function is ov_read. This is what decompresses the file into a PCM stream. The ov_read function takes as input a pointer to an OggVorbis_File structure, a buffer of bytes, the length of that buffer (along with some parameters that tell it if you want big-endian or little-endian output), the size of your platform's word, and whether you want signed or unsigned data.

The last parameter to ov_read is a pointer to an int denoting the current logical bitstream. For simple decoding, what you want to do here is just set an int to zero, and pass the address of that int to all ov_read calls. This frees you from having to worry about logical bitstreams; however, if you're curious, check out the Ogg Vorbis documentation.

The ov_read function may not completely fill up the byte buffer you give it. Thus, it's important to check the return value, which tells you how many bytes you got back. If the return value is zero, you've hit the end of the Ogg Vorbis stream.

Once you're all done reading the file, you close it by using the ov_clear API call. Note that this also closes the FILE pointer; there's no need to call fclose yourself.

Integrating Ogg Vorbis into the Audio Engine

Now that the libraries are installed and you know how the APIs work, you can start slinging some code around. In this section, you'll learn how to load an Ogg Vorbis file into a DirectMusic segment. This sounds tough, but it really isn't. All you need to do is decompress the Ogg Vorbis file into a PCM stream (a.k.a. uncompressed stream), wrap that PCM stream in a wave file header, and pass it off to DirectMusic's Loader for loading into a segment.

You have all of the pieces of the puzzle. One of the Ogg Vorbis example programs (vorbisfile_example.c) illustrates how to use the vorbisfile library to convert an Ogg Vorbis file into a PCM stream, and thanks to MSITStore:C:\Downloads\游戏音频程序设计-Beginning.Game.Audio.Programming\Beginning%20Game%20Audio%20Programming\Premier.Press.Beginning.Game.Audio.Programming.eBook-LiB.chm::/6916final/LiB0020.html#148" target="_blank" >Chapter 4, "MSITStore:C:\Downloads\游戏音频程序设计-Beginning.Game.Audio.Programming\Beginning%20Game%20Audio%20Programming\Premier.Press.Beginning.Game.Audio.Programming.eBook-LiB.chm::/6916final/LiB0020.html#148" target="_blank" >Loading WAV Files," you've already written a CWAVFile class that can create a WAV file from a chunk of uncompressed data. Things are looking good!

I added a new method to CAudioManager, called LoadOggVorbis. Here's the source code:

CSoundPtr CAudioManager:oadOggVorbis(std::string filename) 
{
   std::vector<unsigned char> pcmdata; 
   // this code is based on vorbisfile_example.c,  
   // included in the ogg distribution. 
   char pcmout[4096]; // ogg decoding buffer 
   OggVorbis_File vf;
   int eof=0;
   int current_section; 
   FILE *f = fopen(filename.c_str(), "rb"); 
   if (f == NULL) { Throw("could not open file."); } 
   if(ov_open(f, &vf, NULL, 0) < 0) { 
     Throw("Input does not appear to be an Ogg bitstream."); 
   }
   /* Throw the comments plus a few lines about the bitstream we're
      decoding */
   vorbis_info *vi=ov_info(&vf,-1); 
  // resize the pcmdata vector to the size of the ogg file 
  // two bytes per channel per sample 
  int samples = ov_pcm_total(&vf,-1); 
  int channels = vi->channels;
  int samplerate = vi->rate;
  if (samples > 0) {
    pcmdata.reserve(channels*2*samples);
  }
  while(!eof){ 
    long ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,&current_section); 
    if (ret == 0) {
      /* EOF */ 
      eof=1; 
    } else if (ret < 0) {
      /* error in the stream. Not a problem, just reporting it in 
       case we (the app) cares. In this case, we don't. */ 
    } else {
      /* we don't bother dealing with sample rate changes, etc, but 
       you'll have to*/ 
      // transfer the data out of the ogg buffer and into ours. 
      for (int q=0; q < ret; q++) { 
        pcmdata.push_back(pcmout[q]);
      }
  }
}
/* cleanup */ 
ov_clear(&vf);

// now that we have the PCM data in memory, convert it to a WAV file 
// and handoff to DirectMusic for loading into a segment. 
CWAVFile wavfile;
wavfile.m_AudioFormat = WAVE_FORMAT_PCM; 
wavfile.m_BitsPerSample = 16; 
// 16 bits / 8 bits per byte * channels 
wavfile.m_BlockAlign = 2*channels; 
wavfile.m_ByteRate = samplerate*channels*2;

wavfile.m_NumberOfChannels = channels; 
wavfile.m_SampleRate = samplerate; 
wavfile.SetData(pcmdata.begin(), pcmdata.size()); 
return(LoadSound(wavfile));
}

Most of this source code is a direct cut and paste from vorbisfile_example.c. The vorbisfile_example.c reads an Ogg Vorbis stream from stdin and writes an uncompressed PCM stream to stdout; I've modified it so that it reads an Ogg Vorbis stream from a FILE pointer and writes it into a vector of unsigned chars.

Note that this code knows the output wave is going to be 16 bits, because it specified a 16-bit word size to the ov_read function by passing 2 as the fifth parameter. If you wanted an 8-bit wave file, you'd pass 1 instead.

Once the PCM stream is in the pcmdata vector, the code gives it to a CWAVFile instance (wavfile), along with the details of its format (number of channels, sample rate, and so on). Once wavfile is all put together, the code calls the LoadSound overload you learned about in MSITStore:C:\Downloads\游戏音频程序设计-Beginning.Game.Audio.Programming\Beginning%20Game%20Audio%20Programming\Premier.Press.Beginning.Game.Audio.Programming.eBook-LiB.chm::/6916final/LiB0020.html#148" target="_blank" >Chapter 4 to read the wave file class and construct a DirectMusic segment from it. Nothing to it!

 楼主| 发表于 2006-10-24 16:46:45 | 显示全部楼层

CONCLUSION

In this chapter, you learned how to use the open-source Ogg Vorbis codec as an alternative to MP3 and WMA. However, there's much more to Ogg and Vorbis than just how to decode them. I encourage you to experiment around with the other Vorbis libraries, and to look at the technical specs through which Vorbis accomplishes its magic—it's fascinating reading.

This wraps up the tour of compressed file formats. In the MSITStore:C:\Downloads\游戏音频程序设计-Beginning.Game.Audio.Programming\Beginning%20Game%20Audio%20Programming\Premier.Press.Beginning.Game.Audio.Programming.eBook-LiB.chm::/6916final/LiB0048.html#305" target="_blank" >next chapter, you'll learn how to read and play tracked music formats, a staple of the demo scene, and as you'll see, also quite useful in game programming.

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-5-22 01:36

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表