为啥核心 C 或 C++ 文本不提及声音或图形?

Posted

技术标签:

【中文标题】为啥核心 C 或 C++ 文本不提及声音或图形?【英文标题】:Why don't core C or C++ texts mention sound or graphics?为什么核心 C 或 C++ 文本不提及声音或图形? 【发布时间】:2019-08-29 20:49:29 【问题描述】:

为什么这些“圣经”式的编程书籍应该是全面的,却没有提到任何关于编程声音或图形的内容?

我的 C 编程语言第二版书今天由 Brian Kerninghan 和 Dennis Ritchie 寄来,我认为这本书应该是全面的,但我首先注意到的是它非常薄。除了我们已经学过的基本知识之外,它似乎并没有真正谈论太多。

然后我想我应该看看我的 Bjarne Stroustrop 写的 C++ 编程书,这本书要厚得多,看看 IT 对图形和声音的看法,至少按目录看,有 1200 多页,图形或声音上似乎也没有任何内容。

图形和声音是否是某种额外的主题,需要专业书籍或某些特定图书馆或其他东西的东西?

因为在核心语言本身中肯定有一些关于声音和图形的基础知识,不是吗?

如果没有,从哪里开始学习图形和声音编程?

【问题讨论】:

C 和 C++ 没有声音或图形的概念。 因为那不是 C/C++ 的一部分。这些是编程语言,而不是框架。您可以为特定的声音/图形库获取一本书以了解它。 “图形和声音是否是某种额外的主题,需要专业书籍或某些特定图书馆或其他东西的东西?”肯定是的! 强烈反对以“过于宽泛”而结束此问题的决定。有足够的公开信息可以为这个问题提供一个好的、引用的答案。 总而言之,它会使 C++ 或 C 标准混乱以涵盖针对特定硬件和操作系统的要求,这不是编程语言的目的。 【参考方案1】:

声音和图形不属于 C 或 C++ 编程语言。 C 和 C++ 标准仅定义了必须扩展以提供其他服务的核心语言。

总的来说,C 和 C++ 是抽象编程语言。它们为输入和输出指定了一些特性,这些特性受解释和实现选择的影响,但它们没有指定与设备的交互,包括声音系统或图形显示。它们指定了使用数据进行计算的功能以及用于交互和存储的最少规定。

C 和 C++ 标准定义了核心语言。这些核心语言以各种方式扩展,包括:

为任何类型的服务提供外部库,包括声音和图形功能。 使用volatile 对象与机器进行交互,包括连接到处理器的设备。 通过在编译器中支持额外的关键字或语言结构,为语言构建更多功能。

【讨论】:

【参考方案2】:

C++(和 C)没有图形库作为其标准库的一部分

这让许多新手程序员非常懊恼。

C++ 目前缺少图形库的原因是多种多样的。有人提议将 2d graphics library 添加到 C++ 标准中,但多次添加失败,并且到今年为止或多或少已失效。

Reddit 上有一些文章试图详细说明问题出在哪里,我将在下面链接,但我会总结基本问题:

首先,该提案是针对本质上并非所有架构 + 操作系统都可以支持的功能。任何可行的图形 API 都需要有一些可由操作系统支持的基本组件,例如 Surface(要在其上绘制的东西)、显示器以及用于在该表面上绘制任意图像并将它们呈现给显示器的命令。许多操作系统都有这样的功能:例如 Windows、Linux、MacOS。但是更多的人没有这样做,并且尝试构建一个 API,其中整个 API 可能被无法提供必要功能的操作系统渲染为无效是很麻烦的。标准库的理念是,它为所有正确实现它的编译器提供功能,而不能保证这种保证的功能本质上是不合适的。

第二个问题是对于如何与库进行交互几乎没有达成一致意见。像 Java、Python 或 BASIC(一些变体)提供的基本 2D 图形 API 可以通过多种方式实现,每种方式都有相当大的优点和缺点,而提案的作者似乎没有应该如何实施的连贯愿景。

特别是,现代图形在很大程度上是异构计算的问题,介于 DirectX11/OpenGL 4.x 尝试实现其 API 的方式(前者比后者更重要......),或者DirectX12/Vulkan 代表了“尽可能接近金属”的尝试,而 C++ 标准库缺乏很多有价值的工具来处理这些功能。

std::future 之类的工具可能已经足够了,但根据我在图形编程方面的经验,我怀疑它是否足够,即使是这样,你也会有一个问题:你是否想要 标准库中的一个图形库,它以这种迟钝的术语实现。多年来,这一直阻碍了 Networking 提案,甚至只是在 C++23 中添加,因为还有其他库功能将支持它,例如 Executors 提案,Networking 库非常依赖它。

还有很多其他方面的问题,但我将把它留在那两个大的方面,因为它们不仅解释了为什么这个具体的提案没有成功,它还解释了为什么很多其他雄心勃勃的做同样的事情的提议也没有得到任何地方——包括许多将音频库添加到 C++ 的提议。

那么你能做些什么呢?

对于图形,您需要两件事(至少):

用于获取 Windows/Sur​​faces/etc 的 API。显示在 用于生成显示图像的 API

前者可以由您的操作系统的本机窗口 API 处理,但您也可以使用 QT、GLFW、SDL 或您喜欢的任何其他为跨平台兼容性而设计的 API。

后者可以由良好的图形 API(如 OpenGL)或(如果您正在为 Windows 环境开发)DirectX (11-) 来处理。如果你想熟悉尖端技术,你也可以使用 Vulkan 或 DirectX12,尽管我现在要警告你,两者都比它们的前辈复杂得多,因为它们除了最基本的基础之外没有抽象任何东西,所以请注意,对于这些人来说,学习曲线要​​陡峭得多。

对于音频处理,我没有任何可以亲自担保的建议(我的经验在这方面比较有限),但有很多 API 是专门为此设计的,所以只需研究一下什么是可用。


参考资料:

    https://www.reddit.com/r/cpp/comments/89q6wr/sg13_2d_graphics_why_it_failed/ https://www.reddit.com/r/cpp/comments/89we31/2d_graphics_a_more_modest_proposal/

【讨论】:

【参考方案3】:

简单地说(来自@NathanOliver 的评论):C 和 C++ 没有声音或图形的概念。

如您所料,图形和声音是需要其他类型书籍的额外主题。

大部分这些东西都是从硬件中抽象出来的,并且通常依赖于操作系统。 以 Linux 上的/dev/dsp 为例。它是 OSS 的一部分,是一种允许您播放音频的抽象。您可以在标准 C 或 C++ 中与它进行交互,但它并不适用于所有平台。

【讨论】:

【参考方案4】:

对于某些历史观点,至少在 C:

曾几何时,核心 C 语言甚至没有涵盖文件的 I/O。核心 C 语言涵盖了语言的语法,那就是 it。如果您想对文件进行 I/O,那么您可以包含 <stdio.h> 并调用这些函数...但它们只是库中的外部函数,您可以使用它们,也可以不使用它们,它们不像语言的一部分或任何东西。 (你可能会在 K&R 的副本中找到你刚才所说的或多或少我刚才所说的语言。)

现在,当第一个 ANSI C 标准于 1989 年或任何时候问世时,它确实涵盖了几个当时的标准库,因此<stdio.h> 中的函数(以及<string.h><math.h> 和其他几个)成为该语言的正式部分。但这是一个相当显着的变化。

但是从来没有<stdgraphics.h>,所以没有一个可以标准化的。 (当然现在还没有。)在 1970 年代,几乎没有人在做计算机音频,所以机会就更少了。

(早期的 Unix 确实有一个不错的、简单的 2D 图形库,<plot.h>,甚至可能除了我之外还有一些恐龙仍在使用它,但我认为没有人考虑过尝试推动它作为更广泛的标准。今天的GNU libplot 是它的后代。)

基本上,C 从未渴望成为像 Python 这样的“平台”语言。现在,它作为一种低级、独立于平台的“系统”语言已经根深蒂固,我认为这些“更高级别”功能中的任何一个都不会被添加到其中。

【讨论】:

【参考方案5】:

ISO C++ 确实有一个声音和图形(和输入)研究组:

SG13、HMI 和 I/O(人机界面):选定的低级输出(例如图形、音频)和输入(例如键盘、指针)I/O 原语。

当前处于活动状态(处于非活动状态之后)。

【讨论】:

【参考方案6】:

音频可能比图形更像是标准化的雷区(我注意到,还没有人提到运动视频 - 请参阅下面的编解码器)。根据所讨论的应用程序,它至少可以在这些抽象级别上运行(从低到高列出):

原始 PCM 样本。 适用于音频编解码器的数据流(例如 MPEG 第三层、AAC)。 MIDI - 或其他按音符指示音序器的方式 程序化音频例如SuperCollider

PCM 音频

取第一个,这可能是最通用和最便携的。至少,它需要双缓冲区或循环缓冲区的音频硬件(或更常见的是软件抽象),输出样本实时写入其中以输出到某处。这里有很多参数,例如采样率、通道数、采样位深度、延迟、字节序、符号以及是否使用推送或拉取(事件驱动)模型来呈现数据缓冲区。

专业应用程序的低延迟音频需要实时线程(因此,需要一个提供它们的操作系统),并仔细管理系统资源。

成功的 API 是 CoreAudio(仅限 MacOS、ios)、ASIO、DirectX 和一大堆 Windows API(专业软件总是使用 ASIO)、Jack、ALSA

编解码器

其中很多是专有的和受专利保护的。各种 Web 标准在指定它们时遇到了很大的困难——而且它们的限制性远低于 ISO 规则。并非所有实现都实现了所有这些。

MIDI

这至少是相当标准的(尽管业界花费了近 25 年以上的时间来替换它)。 20 年前,你一直在用它来驱动专业的合成硬件(几乎所有智能手机时代之前的手机和游戏机都有一个,主要由 Yamaha 制造),但现在音序器通常驱动软件合成器,任何像样的是专有的商业软件。也没有两个实现听起来相同,这使得它们在可移植性方面基本上没有用处。

程序化音频

此时,您将定义一种完全独立的编程语言。

结论

祝你好运,尝试将其中任何一项标准化 - 几十年来,音乐软件行业的尝试一再失败,标准机构更加宽松。

具有某种讽刺意味的是,几乎所有严肃的音频软件都是用 C++ 实现的——通常因为它本身没有任何类型的音频抽象。

【讨论】:

【参考方案7】:

图形支持变化的一些背景知识。

从历史上看,计算机唯一支持的图形是 ASCII 字符。 *(在互联网上搜索“ASCII 艺术”)。

图形被开发出来,但主要有两种风格:位图和矢量。一些系统有一个向量列表(数学类型),并绘制了这些。其他图形设备使用 像素 来显示图像。即使在今天,一些图形控制器也允许您定义自己的“位图”并保留单元格(但它们不支持线条绘制)。

图形一开始是单色的。一种前景色和一种背景色,中间没有阴影。这是为了简化复杂性和成本。其他很快出现的功能:单色阴影和亮度属性。图形控制器最初是每像素一位(打开或关闭,“关闭”是背景颜色)。图形控制器随后扩展为每像素允许更多位,单色仍然是最受欢迎的。你可以有灰色阴影并改变强度。一些控制器还具有用于“闪烁”和其他属性的位。

随着硬件成本越来越低,图形控制器开始采用更高级的功能:颜色和位位图。现在你可以有 4 位红色,4 位绿色,4 位蓝色。这允许在组合强度位时使用多种颜色并扩展阴影。图形控制器开始拥有自己的内存以及将位图数据从 CPU 内存传输到图形内存区域的能力,通常称为位块。控制器先进到允许使用 blitting(AND、OR、XOR 等)进行布尔运算。

现代高级图形控制器被认为是独立于 CPU 的计算机。它们不仅有自己的内存,而且还有可供 CPU 用来并行执行处理的内核。这些控制器中的许多都具有在硬件中实现的通用算法(例如屏幕旋转、碰撞检测)。它们有多个缓冲区,因此 CPU 可以绘制到一个缓冲区,而 GPU 显示另一个缓冲区(有助于提高图形速度以支持动画)。

C 和 C++ 是标准。也就是说,您应该能够将标准 C 语言程序编译到任何支持该标准的平台上。图形的问题在于没有标准。一些图形控制器只支持文本和位图,不支持画线。台式 PC 具有不同程度的图形功能,具体取决于插入系统的图形板。因此,没有太多可以标准化的东西。此外,图形技术不断变化(改进)的速度比开发语言标准的速度更快。

最后,让我们谈谈低级编程。为了从图形中获得最大的性能,代码需要直接访问硬件;有时还利用处理器的功能。任何置于语言中的图形 API 都必须是抽象的以支持图形概念;由于减法,可能效率不高。为了性能,图形硬件的低级编程仍然存在。编译器编写器不是图形导出,一般情况下会使用库或编译器。支持这么多组合(如上面的历史部分所示)。

请记住,C 和 C++ 语言是“物有所值”。如果我在嵌入式系统上不使用任何图形,我应该能够拥有没有图形支持的编译器代码。与支持图形的其他语言(如 Java)相比,这些语言拥有更广泛的受众。

【讨论】:

以上是关于为啥核心 C 或 C++ 文本不提及声音或图形?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C 或 C++ 书籍不包含任何有关网络的内容? [关闭]

使用 C++ 或 C# 实时录制声音

如何在 C++ 中播放声音 [关闭]

C++ / W32 - 录制声音、Direct Show 或 WaveInOpen?

如何在c ++中播放声音[关闭]

为啥 volatile 在多线程 C 或 C++ 编程中没有用?