I have been working on my ANC project. For this I have two microphone inputs and one loud speaker output, but initially I am using single microphone and dspStreamingPassthrough to pass microphone input to loud speaker. Here is my code
% Initialization
numIterations = 500;
% Construct sources (for all inputs)
src1 = dsp.AudioRecorder('DeviceName','Mikrofon (USB-Audiogerät)','NumChannels',1);
% Construct sinks (for all outputs)
sink1_1 = dsp.SpectrumAnalyzer('SampleRate',44100, ...
'PlotAsTwoSidedSpectrum',false, ...
'ShowLegend',true);
sink1_2 = dsp.TimeScope('BufferLength',44100, ...
'SampleRate',44100, ...
'TimeSpan',1, ...
'ShowLegend',true, ...
'ShowGrid',true, ...
'YLimits',[-0.5 0.5]);
sink1_3 =
dsp.AudioPlayer('BufferSizeSource','Property','BufferSize',1024,...
'QueueDuration',0,'OutputNumUnderrunSamples',true);
sink1_3.DeviceName = 'Lautsprecher (USB-Audiogerät)';
% Stream processing loop
clear dspStreamingPassthrough;
for i = 1:numIterations
% Sources
in1 = step(src1);
% User Algorithm
out1 = dspStreamingPassthrough(in1);
% Sinks
step(sink1_3,out1);
step(sink1_1,out1);
step(sink1_2,out1);
nUnderrun=step(sink1_3,out1);
end
% Clean up
release(src1);
release(sink1_1);
release(sink1_2);
I am using Windows DirectSound Audio driver ( I cannot use ASIO driver as I cannot access individual audio devices names. ! ) Now I have the audio latency of 1.2 seconds i.e if I say ''hello'' in microphone now, after 1.2 seconds speaker is saying ''hello''(this is absolutely with out any audio input data processing just 'dspStreamingPassthrough'). How to reduce this incredible delay ?
For my project of 1 meter length pipe(air duct), I should be able to process the data in 1.7 msec or less !! I have tried with lowest 'BufferSize' and lowest 'QueueDuration' possible !!
What other parameters can influence to speed up this process? Is it possible with MATLAB or not ?
PS: -sorry for whole code. -I am using a cheap quality Sound card (7 euros)
DirectSound has way higher latency than ASIO because DirectSound is not suited for low-latency apps. DSP System Toolbox does not support WASAPI yet.
The latency performance of these objects was greatly improved starting in 15a. I am not sure which version you are running but try and upgrade to 15a or higher.
As for tuning your latency, try the following:
* Set the Queue Duration property to 0 seconds for both player and recorder.
* For the recorder, match the SamplesPerFrame and BufferSize property.
* For the player, ensure that the size of the data matches the BuferSize property.
The BufferSize property is the size at which the sound card operates.
If you get drops, increase the BufferSize value. There can be many reasons for the drops:
* The algorithm you are running is not faster than BufferSize/SampleRate
* The soundcard is not able to operate at this BufferSize. Some sound-cards allow you to modify this when using ASIO.
* Limitation of the player/recorder objects.
Hope this helps.
Dinesh
Related
When creating a new CIContext with Metal device one has to provide which device (a GPU) to use:
let context = CIContext(
mtlDevice: device
)
On my MacBook Pro for the development purposes I always pick the device associated with the screen with MTLCreateSystemDefaultDevice() method:
guard
let device:MTLDevice = MTLCreateSystemDefaultDevice()
else {
exit(EXIT_FAILURE)
}
However on a Mac Pro which will be used in production in a headless mode there are two GPU cards that I can target. In order to get all available devices one can use MTLCopyAllDevices() method which gives the following output on my Mac Pro:
[
<MTLDebugDevice: 0x103305450> -> <BronzeMtlDevice: 0x10480a200>
name = AMD Radeon HD - FirePro D700
<MTLDebugDevice: 0x103307730> -> <BronzeMtlDevice: 0x104814800>
name = AMD Radeon HD - FirePro D700
]
This Mac Pro will be utilised heavily with hundreds of small tasks per second and every time the new task comes in I need to select a GPU device on which the task will be processed.
Now the question is - is picking a random device from the above array a good idea:
let devices = MTLCopyAllDevices() // get all available devices
let rand = Int(arc4random_uniform(UInt32(devices.count))) // random index
let device = devices[rand] // randomly selected GPU to use
let context = CIContext(
mtlDevice: device
)
Since there are two equal GPU devices on a Mac Pro, targeting always one will be a waste of resources. Logic tells me that with the above code both GPUs will be utilised equally but maybe I'm wrong and MacOS offer some kind of abstraction layer that will intelligently pick the GPU which is less utilised at the time of execution?
Thank you in advance.
Why not just alternate between them? Even if you're committing command buffers from multiple threads, the work should be spread roughly evenly:
device = devices[taskIndex % devices.count]
Also, make sure to avoid creating CIContexts for every operation; those are expensive, so you should keep a list of contexts (one per device) instead.
Note that if you're doing any of your own Metal work (as opposed to just Core Image filtering), you'll need to have a command queue for each device, and any resources you want to use will need to be allocated by their respective device (resources can't be shared by MTLDevices).
This is a follow-up to a previous question:
OSX CoreAudio: Getting inNumberFrames in advance - on initialization?
I am trying to figure out what will be the AudioUnit API for possibly setting inNumberFrames or preffered IO buffer duration of an input callback for a single HAL audio component instance in OSX (not a plug-in!).
While I understand there is a comprehensive documentation on how this can be achieved in iOS, by means of AVAudioSession API, I can neither figure out nor find documentation on setting these values in OSX, whichever API.
The web is full of expert, yet conflicting statements ranging from "There is an Audio Unit API to request a sample rate and a preferred buffer duration...", to "You can definitely get the number of frames, but only for the current callback call...".
Is there a way of at least getting (and adapting to) the inNumberFrames or the audio buffer length offerd by the system, for the input-selected sampling rates in OSX? For example, for 44.1k and its multiples (this seems to work partly), as well as for 48k and its multiples (this doesn't seem to work at all, I don't know where's the hack which allows for adapting the buffer lenfth to these values)? Here's the console printout:
Available 7 Sample Rates
Available Sample Rate value : 8000.000000
Available Sample Rate value : 16000.000000
Available Sample Rate value : 32000.000000
Available Sample Rate value : 44100.000000
Available Sample Rate value : 48000.000000
Available Sample Rate value : 88200.000000
Available Sample Rate value : 96000.000000
.mSampleRate = 48000.00
.mFormatID = 1819304813
.mBytesPerPacket = 8
.mFramesPerPacket = 1
.mBytesPerFrame = 8
.mChannelsPerFrame = 2
.mBitsPerChannel = 32
.mFormatFlags = 9
_mFormatHumanReadable = kAudioFormatFlagIsFloat
kAudioFormatFlagIsPacked
kLinearPCMFormatFlagIsFloat
kLinearPCMFormatFlagIsPacked
kLinearPCMFormatFlagsSampleFractionShift
kAppleLosslessFormatFlag_16BitSourceData
kAppleLosslessFormatFlag_24BitSourceData
expectedInNumberFrames = 512
Couldn't render in current context (Error -10863)
The expected inNumberFrames is read from the system:
UInt32 expectedInNumberFrames = 0;
UInt32 propSize = sizeof(UInt32);
AudioUnitGetProperty(gInputUnitComponentInstance,
kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global,
0,
&expectedInNumberFrames,
&propSize);
Thanks in advance for pointing me at the right direction!
See this Apple Technical Note: https://developer.apple.com/library/mac/technotes/tn2321/_index.html#//apple_ref/doc/uid/DTS40013499-CH1-THE_I_O_BUFFER_SIZE
See the OS X example code in this technical note for GetIOBufferFrameSizeRange(), GetCurrentIOBufferFrameSize(), and SetCurrentIOBufferFrameSize().
Note that there is an API property returning an allowed range, and an error return on the property setter. Also note the various Mac power saving modes may change the buffer size while an app is running, so the actual buffer size, inNumberFrames, may not stay constant, or even be known until the Audio Unit starts running.
If you get unusual buffer sizes (not a power of 2), it may be that the actual audio hardware on a particular Apple product model has a fixed or limited range of audio sample rates, and thus OS software is being used to resample and thus resize the buffers being sent to audio unit callbacks depending on that hardware, if the app requests a sample rate not supported by the actual codec chips on the circuit board.
I am trying to simply record sound through an external sound card: RME Fireface 400.
This is the code I am using:
AO = audioplayer(mls_o,fs,16,5); % mls_o is the signal that is played.
AI = audiorecorder(fs,16,2,5); % 2 CHANNELS BUT HOW DO I ASSIGN THEM
play(AO);%playing
recordblocking(AI,1,2);%recording
y_rec=getaudiodata(AI);
delete(AI);% Deleting the objects
delete(AO);
I can only chose the number of channels, but not to address them.
Audiorecorder only supports 2 channels and Fireface have 8 input channels. I have to use the first two analog: ch5 and ch6. However, by default audio recorder only look 1st and 2nd one, which are mic inputs.
Otherwise do you know any other way of doing that?
I don't think you can do this with just the audiorecorder object. Check out the playrec library and pa-wavplay FileExchange submission, either of which should be capable of doing what you need. I believe Psychtoolbox also allows you to do this, but that might be overkill for your needs.
The documentation for Audio Queue Services under OS 10.6 now includes a pitch parameter:
kAudioQueueParam_Pitch
The number of cents to pitch-shift the audio queue’s playback, in the range -2400through 2400 cents (where 1200 cents corresponds to one musical octave.)
This parameter is usable only if the time/pitch processor is enabled.
Other sections of the same document still say that volume is the only available parameter, and I can't find any reference to the time/pitch processor mentioned above.
Does anyone know what this refers to? Directly writing a value to the parameter has no effect on playback (although no error is thrown). Similarly writing the volume setting does work.
Frustrating as usual with no support from Apple.
This is only available on OSX until iOS 7. If you look at AudioQueue.h you'll find it is conditionally available only on iOS 7. [note: on re-reading I see you were referring to OS X, not iOS, but hopefully the following is cross-platform]
Also, you need to enable the queue for time_pitch before setting the time_pitch algorithm, and only the Spectral algorithm supports pitch (all of them support rate)
result = AudioQueueNewOutput(&(pAqData->mDataFormat), aqHandleOutputBuffer, pAqData,
0, kCFRunLoopCommonModes , 0, &(pAqData->mQueue));
// enable time_pitch
UInt32 trueValue = 1;
AudioQueueSetProperty(pAqData->mQueue, kAudioQueueProperty_EnableTimePitch, &trueValue, sizeof(trueValue));
UInt32 timePitchAlgorithm = kAudioQueueTimePitchAlgorithm_Spectral; // supports rate and pitch
AudioQueueSetProperty(pAqData->mQueue, kAudioQueueProperty_TimePitchAlgorithm, &timePitchAlgorithm, sizeof(timePitchAlgorithm));
I'm now creating an Application using speech recognition.To check the Audio Power coming in through the microphone,
I wrote a method as follows.
-(void)checkPower(AudioqueRef)queue{
UInt32 expectedSize= sizeof(AudioQueueLevelMeterState);
AudioQueueGetProperty(queue,
kAudioQueueProperty_CurrentLevelMeter,
audioLevels,
expectedSize);
NSLog(#"average:%f peak:%f",audioLevels.mAveragePower,audioLevels.mPeakPower);
}
I found that sometimes mAveragePower was larger than mPeakPower,
and when mAveragePower was 1.0, in other words, averagePower
is regarded as max, mPeakPower was lower than 1.0.
I think that generally this result is inpossible.
please Let me know if you have any information about sound power on CoreAudio.
thanks.
I think mPeakPower means channel power at CURRENT moment & mAveragePower - average channel power for ALL record time, and if it's right your result possible.