Я хочу воспроизвести звуковой сигнал в своем Mac Os X и указать продолжительность и частоту. В Windows это можно сделать с помощью Функция звукового сигнала (Console.Beep в .Net) . Есть ли что-то подобное в Mac? Я знаю о NSBeep, но он не принимает никаких параметров.
Звуковой сигнал с пользовательской частотой и продолжительностью
Ответы (4)
На Mac звук системного оповещения представляет собой сэмпл (предварительно записанный) звук, который выбирает пользователь. Часто это совсем не похоже на звуковой сигнал — это может быть гудок, удар, рев или другой звук, который не может быть простой постоянной формой волны фиксированной формы, частоты и амплитуды. Это может быть даже запись голоса пользователя, или отрывок из телешоу, или фильма, или игры, или песни.
Это также не обязательно должен быть только звук. Одним из вариантов специальных возможностей является мигание экрана при воспроизведении звукового сигнала; это происходит автоматически при воспроизведении звука предупреждения (или пользовательского звука предупреждения), но не при воспроизведении звука через обычные API-интерфейсы воспроизведения звука, такие как NSSound.
Таким образом, нет простого способа воспроизвести собственный звуковой сигнал заданной и постоянной формы, частоты и амплитуды. Любой такой звуковой сигнал будет отличаться от выбранного пользователем звука оповещения и может вообще не восприниматься пользователем.
Чтобы воспроизвести звуковой сигнал на Mac, используйте NSBeep
или немного более сложный вариант AudioServicesPlayAlertSound
. Последний позволяет вам использовать пользовательские звуки, но даже они должны быть предварительно записаны или, по крайней мере, сгенерированы вашим приложением заранее с использованием большего количества кода Core Audio, чем стоит писать.
Я рекомендую использовать NSBeep
. Это одна строка кода для уважения выбора пользователя.
В PortAudio есть кроссплатформенный код C для этого: https://subversion.assembla.com/svn/portaudio/portaudio/trunk/examples/paex_sine.c
Этот конкретный образец генерирует тоны для левого и правого динамика, но не показывает, как рассчитываются частоты. Для этого вы можете использовать формулу в этом коде: -constantly">Есть ли в Java библиотека для постоянного излучения определенной частоты?
Мне нужна была аналогичная функциональность для приложения. Я закончил тем, что написал небольшой многоразовый класс, чтобы справиться с этим для меня.
Многоразовый класс для генерации простых звуковых тонов синусоидальной формы с заданной частотой и амплитудой. Может воспроизводиться непрерывно или в течение заданного времени.
Интерфейс довольно прост и показан ниже:
@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
Вот способ сделать это с помощью более новых API-интерфейсов AVAudioEngine/AVAudioNode и 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