3

我想在我的 Mac Os X 中播放哔声并指定持续时间和频率。在 Windows 上,可以使用Beep 功能(.Net 中的Console.Beep )来完成。Mac有什么等价的吗?我知道 NSBeep 但它不带任何参数。

4

4 回答 4

5

在 Mac 上,系统警报声音是用户选择的采样(预录)声音。它通常听起来不像哔哔声——它可能是喇叭声、砰砰声、喇叭声或其他不能作为固定形状、频率和幅度的简单恒定波形的声音。它甚至可以是用户声音的录音,或者是电视节目、电影、游戏或歌曲的剪辑。

它也不必只是一个声音。可访问性选项之一是在播放警报声时闪烁屏幕;这会在您播放警报声音(或自定义警报声音)时自动发生,但不会在您通过常规声音播放 API(如 NSSound)播放声音时发生。

因此,没有简单的方法可以播放具有指定和恒定形状、频率和幅度的自定义哔声。任何这样的蜂鸣声都会与用户选择的警报声音不同,并且用户可能根本察觉不到。

要在 Mac 上播放警报声,请使用NSBeep或稍微复杂一点的AudioServicesPlayAlertSound. 后者允许您使用自定义声音,但即使这些声音也必须预先录制,或者至少由您的应用程序预先使用更多的 Core Audio 代码生成,而不是值得编写。

我建议使用NSBeep. 这是尊重用户选择的一行代码。

于 2012-09-22T22:16:20.200 回答
2

PortAudio 在这里有跨平台的 C 代码:https ://subversion.assembla.com/svn/portaudio/portaudio/trunk/examples/paex_sine.c

该特定样本在左右扬声器上产生音调,但没有显示频率是如何计算的。为此,您可以使用此代码中的公式:Java 中是否有一个库可以不断发出特定频率?

于 2012-09-23T02:30:48.710 回答
2

我需要一个类似的应用程序功能。我最终编写了一个小型的、可重用的类来为我处理这个问题。

来源在 GitHub

一个可重用的类,用于生成具有指定频率和幅度的简单正弦波形音频。可以连续播放或指定持续时间。

界面相当简单,如下所示:

@interface TGSineWaveToneGenerator : NSObject
{
    AudioComponentInstance toneUnit;

@public
    double frequency;
    double amplitude;
    double sampleRate;
    double theta;
}

- (id)initWithFrequency:(double)hertz amplitude:(double)volume;
- (void)playForDuration:(float)time;
- (void)play;
- (void)stop;

@end
于 2013-08-16T15:13:31.757 回答
0

这是使用较新的 AVAudioEngine/AVAudioNode API 和 Swift 执行此操作的方法:

import AVFoundation
import Accelerate

// Specify the audio format we're going to use
let sampleRateHz = 44100
let numChannels = 1
let pcmFormat = AVAudioFormat(standardFormatWithSampleRate: Double(sampleRateHz), channels: UInt32(numChannels))

let noteFrequencyHz = 440
let noteDuration: NSTimeInterval = 1

// Create a buffer for the audio data
let numSamples = UInt32(noteDuration * Double(sampleRateHz))
let buffer = AVAudioPCMBuffer(PCMFormat: pcmFormat, frameCapacity: numSamples)
buffer.frameLength = numSamples  // the buffer will be completely full

// The "standard format" is deinterleaved float, so we can assume the stride is 1.
assert(buffer.stride == 1)
for channelBuffer in UnsafeBufferPointer(start: buffer.floatChannelData, count: numChannels) {
    // Generate a sine wave with the specified frequency and duration
    var length = Int32(numSamples)
    var dc: Float = 0
    var multiplier: Float = 2*Float(M_PI)*Float(noteFrequencyHz)/Float(sampleRateHz)
    vDSP_vramp(&dc, &multiplier, channelBuffer, buffer.stride, UInt(numSamples))
    vvsinf(channelBuffer, channelBuffer, &length)
}

// Hook up a player and play the buffer, then exit
let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
engine.attachNode(player)
engine.connect(player, to: engine.mainMixerNode, format: pcmFormat)
try! engine.start()
player.scheduleBuffer(buffer, completionHandler: { exit(1) })
player.play()

NSRunLoop.mainRunLoop().run()  // Keep running in a playground
于 2016-05-14T03:06:03.647 回答