Core Audio MIDI Synth AU & MusicPlayer - Cannot be pulled by AudioUnitRender programmatically - core-audio

I have an AUGraph with AudioUnits. My MIDI Synth AudioUnit was created by this:
AudioComponentDescription midiSynthDesc;
midiSynthDesc.componentType = kAudioUnitType_MusicDevice;
midiSynthDesc.componentSubType = kAudioUnitSubType_MIDISynth;
Then I load the SF2 File into the MIDI AudioUnit:
NSURL *bankURL = [[NSBundle mainBundle] URLForResource:#"Combined" withExtension:#"sf2"];
AudioUnitSetProperty(midiSynthUnit,
kMusicDeviceProperty_SoundBankURL,
kAudioUnitScope_Global,
0,
&bankURL,
sizeof(bankURL));
I have this SF2 loaded MIDI-Synth AudioUnit connected to Remote-IO AudioUnit, then I added MusicPlayer to this AUGraph to play:
MusicPlayerSetSequence(musicPlayer, musicSequence);
NewMusicSequence(&musicSequence);
MusicSequenceFileLoad(musicSequence, (__bridge CFURLRef)midiFileURL, 0, 0)
MusicSequenceSetAUGraph(musicSequence, processingGraph);
MusicPlayerPreroll(musicPlayer);
MusicPlayerStart(musicPlayer);
And it works with the Remote-IO, I can hear the MIDI file playing.
However, if I pull the MIDI Synth Audio Unit programmatically, trying to render the MIDI File into Raw Audio Data and then write into m4a file:
OSStatus err = noErr;
err = AudioUnitRender(midiSynthUnit, &flags, &inTimeStamp, busNumber, numberFrames, bufferList);
No audio data can be read ( bufferList's mData == 0 Always).
No matter how many times I call AudioUnitRender, MusicPlayerGetTime always tells me that the current beat of the Music Player is 0:
Float64 currentBeat;
MusicPlayerGetTime(musicPlayer, &currentBeat);
Can anybody tell me why?
Any suggestion how to read the MIDI File with SF2 soundfont file and convert into raw audio data / render MIDI into m4a file?
Thanks

I've not tested this, but maybe you can try another SO question & answer as inspiration.
Anyway, what I know about AudioToolbox's MusicPlayer is that it works in real time only. If the MIDI sequence is two minutes long, it will take two minutes at least to render the audio file. If you prefer batch processing, where the rendering speed is only limited by the speed of your system, CPU, memory and IO, then I recommend you to use an alternative like FLuidSynth

Related

reading from rtsp stream on mac os x using popen and read is failing

I am generating an rtsp stream using gstreamer in an iOS app and trying to use ffmpeg in a Mac OS X audio driver that I wrote using XCode to strip the audio out of the stream and then pump the audio to Skype or Zoom or whatever. All the code is written in the 'C' old-fashioned programming language. I do get a FILE* that is not NULL back from a popen function call to execute ffmpeg on the input rtsp stream. But once I get that FILE* object and try to read binary data from it, it returns that zero bytes have been read. Here is the code:
FILE *readPipeFromFFMPEG = popen("Contents/MacOS/ffmpeg -i rtsp://192.168.0.30:8554/test -vn -acodec copy -flush_packets pipe:1", "r+");
int pipeFD = fileno(readPipeFromFFMPEG);
char *buffer = (char*)calloc(inIOBufferFrameSize * 8, 1);
numBytesRead = read(pipeFD, buffer, inIOBufferFrameSize * 8);
free(buffer);
pclose(readPipeFromFFMPEG);
but numBytesRead is always coming back as zero. Does anybody have any clue what I need to do to get this working properly? It seems like maybe a permissions issue where I do not have permission to read from the stream? Or maybe my ffmpeg parameters are incorrect? I am able to open up the stream in VLC and OBS Studio no problem and it displays the video frames and plays the audio. I am really stuck I need help! I must be missing something totally obvious because when I run OBS Studio or VLC it shows in the iPhone app the requests from the client because it prints out information that the audio and video packets are being requested but when the audio driver is running nothing is printed out in the iPhone app.

Playback raw sound data in memory using MFC functions

I have an MFC based project that decodes some data and generates 16 bit 48000 Hz raw wav audio data
The program continuously generates wav audio data in real time
Are there any functions in MFC that will let me play back the audio data in the sound card? I have been googling around for a while and the consensus seems to be that MFC doesn't have this feature. I have also found this tutorial that shows how to playback a wav file using PlaySound() function, but it looks like it is only for wav files and even if it plays audio data in memory, that data has to be prepared in the form of a full wav file with all the header information, while I need to play back raw wav data generated in real time
I have also seen people suggest using Direct X, but I feel like something like this should be possible using basic windows library functions without having to use any other extra libraries. I also found this tutorial for creating and reading wav files in an MFC based project, but it's not really clear how to use it to play raw wav data in memory. This tutorial uses waveOutOpen() function to playbakc the wav file, and it looks like this is probably what I need, but I cannot find a simple tutorial that shows how to use it.
How do I playback raw wav audio in memory in an MFC Dialog based project? I am looking for something where I can specify pointer to the wav data, number of samples, bits and sampling frequency and the function would playback the wav data for me. A basic working example such as generating a sinewave and playing it back will be appreciated. If directx is the only way to do this then that's fine as well.

Error while saving captured audio using AVAssetWriterInput

We are developing an audio recording application for 10.7.5 and above.
We are using AVCaptureAudioDataOutput to capture audio and data is written using AVAssetWriterInput.
Properties set to the AVAssetWriterInput as below:
AVFormatIDKey : kAudioFormatMPEG4AAC
AVSampleRateKey : This values is taken from device using below code
AudioStreamBasicDescription streanDesc;
UInt32 propSize = sizeof(AudioStreamBasicDescription);
AudioDeviceGetProperty(mInputDevice, 0, YES, kAudioDevicePropertyStreamFormat, &propSize,&streanDesc);
AVNumberOfChannelsKey : This is taken from AudioStreamBasicDescription.
AVEncoderBitRateKey : This is hardcoded to 96000.
This works fine for most of the audio device except for USB mic of sample rate 32khz and iSight device with sample rate 48khz.
When we use these two devices as input audio device, while writing audio data we are getting the following error -
Error Domain=AVFoundationErrorDomain Code=-11821 "Cannot Decode" UserInfo=0x279470 {NSLocalizedFailureReason=The media data could not be decoded. It may be damaged., NSUnderlyingError=0x292370 "The operation couldn’t be completed. (OSStatus error 560226676.)", NSLocalizedDescription=Cannot Decode}".
However in case of USB mic if we hardcode the AVSampleRateKey to 44100 it works perfectly fine but does not work for iSight device.
What is correct value to be provided for AVSampleRateKey? Can any one help me to resolve this issue.

Playing large recorded audio files stored in Isolated Storage

I am recording audio using the XNA Microphone class and saving the recorded data in isolated storage in wav format.If the length of audio is small my app is working fine.But as it increases the memory consumed by the app also increases,which drastically slows down the device.The following code is used to play the audio
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = isoStore.OpenFile(AudioFilePath, FileMode.Open))
{
sound = SoundEffect.FromStream(FileStream);
sound.Play();
}
}
Any suggestion on how to handle the memory issue while playing large audio files.Or how can i save the PCM in other formats (wma,mp3) to reduce the size.
SoundEffect isn't intended for playing long pieces of audio. As the name suggests it is intended for short pieces and also playing lots of them, possibly at the same time.
To play longer pieces of audio you shoudl consider the MediaElement.

rendering an audio stream (WASAPI / WINAPI )

i'm currently reading the documentation of MSDN to render a stream to an audio renderer..
or in other word, to play my captured data from microphone.
http://msdn.microsoft.com/en-us/library/dd316756%28v=vs.85%29.aspx
this example provides example.
My problem now is that i couldn't really understand the project flow.
I currently have a different class storing the below parameters which i obtained from the capture process.
these parameters will be continuously re-written as the program captures streaming audio data from the microphone.
BYTE data;
UINT32 bufferframecount;
DWORD flag;
WAVEFORMATEX *pwfx;
My question is,
How does really the loadData() function works.
is it suppose to grab the parameter i'm writing from capture process?
how does the program sends the data to audio renderer, and play it in my speaker.
The loadData() function fills in audio pointed to by pData. The example abstracts the audio source, so this could be anything from a .wav file to the microphone audio that you already captured.
So, if you are trying to build from that example, I would implement the MyAudioSource class, and have it just read PCM or float samples from a file, whenever loadData() is called. Then, if you run that program, it should play the audio from the file out the speaker.

Resources