Ses Birimlerini kullanarak bir müzik kayıt uygulaması kodluyorum ve sonuçta elde edilen M4A dosyamın çok müthiş bir gürültüden başka bir şey çalmasını sağladığım bazı sorunlar yaşıyorum . Bu SO sourcesasreferences'u kullandım ve sorunları gidermek için her şeyi denedim.Dosyaya uzak I/0 çıkışı yazma ve kodlama - Temel Ses
2 düğümlü bir AUGraph
var: çok kanallı bir mikser ve uzak bir G/Ç. Mikserinde iki giriş geri çağırma var: mikrofondan girişi çeken ve ses dosyasından çekilen bir. Mikser çıkışı, I/O ünitesindeki çıkış kapsamının giriş elemanına bağlanır. Bu eşzamanlı G/Ç'yi etkinleştirir.
ben ekledim çıktı bir geri arama ve iki yöntem yakalamak için:
geri arama
static OSStatus recordAndSaveCallback (void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
Mixer* THIS = (__bridge Mixer*)inRefCon;
AudioBufferList bufferList;
OSStatus status;
status = AudioUnitRender(THIS.ioUnit,
ioActionFlags,
inTimeStamp,
0,
inNumberFrames,
&bufferList);
SInt16 samples[inNumberFrames]; // A large enough size to not have to worry about buffer overrun
memset (&samples, 0, sizeof (samples));
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mData = samples;
bufferList.mBuffers[0].mNumberChannels = 1;
bufferList.mBuffers[0].mDataByteSize = inNumberFrames*sizeof(SInt16);
OSStatus result;
if (*ioActionFlags == kAudioUnitRenderAction_PostRender) {
result = ExtAudioFileWriteAsync(THIS.extAudioFileRef, inNumberFrames, &bufferList);
if(result) printf("ExtAudioFileWriteAsync %ld \n", result);}
return noErr;
}
Kayıt Yöntemi:
- (void)recordFile
{
OSStatus result;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *recordFile = [documentsDirectory stringByAppendingPathComponent: @"audio.m4a"];
CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(__bridge CFStringRef)recordFile,
kCFURLPOSIXPathStyle,
false);
AudioStreamBasicDescription destinationFormat;
memset(&destinationFormat, 0, sizeof(destinationFormat));
destinationFormat.mChannelsPerFrame = 1;
destinationFormat.mFormatID = kAudioFormatMPEG4AAC;
UInt32 size = sizeof(destinationFormat);
result = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &destinationFormat);
if(result) printf("AudioFormatGetProperty %ld \n", result);
result = ExtAudioFileCreateWithURL(destinationURL,
kAudioFileM4AType,
&destinationFormat,
NULL,
kAudioFileFlags_EraseFile,
&extAudioFileRef);
if(result) printf("ExtAudioFileCreateWithURL %ld \n", result);
AudioStreamBasicDescription clientFormat;
memset(&clientFormat, 0, sizeof(clientFormat));
UInt32 clientsize = sizeof(clientFormat);
result = AudioUnitGetProperty(ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &clientFormat, &clientsize);
if(result) printf("AudioUnitGetProperty %ld \n", result);
UInt32 codec = kAppleHardwareAudioCodecManufacturer;
result = ExtAudioFileSetProperty(extAudioFileRef,
kExtAudioFileProperty_CodecManufacturer,
sizeof(codec),
&codec);
if(result) printf("ExtAudioFileSetProperty %ld \n", result);
result = ExtAudioFileSetProperty(extAudioFileRef,kExtAudioFileProperty_ClientDataFormat,sizeof(clientFormat), &clientFormat);
if(result) printf("ExtAudioFileSetProperty %ld \n", result);
result = ExtAudioFileWriteAsync(extAudioFileRef, 0, NULL);
if (result) {[self printErrorMessage: @"ExtAudioFileWriteAsync error" withStatus: result];}
result = AudioUnitAddRenderNotify(ioUnit, recordAndSaveCallback, (__bridge void*)self);
if (result) {[self printErrorMessage: @"AudioUnitAddRenderNotify" withStatus: result];}
}
Tasarruf Yöntemi:
- (void) saveFile {
OSStatus status = ExtAudioFileDispose(extAudioFileRef);
NSLog(@"OSStatus(ExtAudioFileDispose): %ld\n", status);
}
Bubenim konsolunda gördükleri şeydir:
Stopping audio processing graph
OSStatus(ExtAudioFileDispose): 0
ExtAudioFileWriteAsync -50
ExtAudioFileWriteAsync -50
ExtAudioFileWriteAsync -50
Benim kod bu işe aldık insanların buna çok benzer geliyor bana, ama açıkça ben ettik önemli bir hata yaptı. Eminim bununla mücadele eden başkaları olmalı.
Herhangi bir fikir sahibi olan var mı?
Teşekkürler.
'recordAndSaveCallback' bitmeden' 'saveFile' yönteminin çağrıldığını görüyoruz. SaveFile çağrılmadan önce AUGraph'ı mı durdunuz? – sbooth
grafiğinizle ilgili herhangi bir sorunu göz ardı etmek için bir deneme olarak, wav gibi daha basit bir format kullanarak denemek ve kaydetmek için iyi bir fikir olabilir. ASBD'nin doğru olması zor olabilir, ancak ASBD'nin (benim fikrim) bir problem olduğunu tespit ederseniz, en azından dosya formatını denemeye odaklanabilirsiniz. – dubbeat
macerror -50'nin komut satırından çalıştırılması şunu verir: Mac OS hatası -50 (paramErr): kullanıcı parametre listesinde hata – morgancodes