Форум программистов, компьютерный форум, киберфорум
Наши страницы

Objective-C

Войти
Регистрация
Восстановить пароль
 
777WSW777
0 / 0 / 0
Регистрация: 26.02.2016
Сообщений: 1
#1

Сохранение в файл выходного потока из AVAudioEngine - Objective-C

26.02.2016, 15:41. Просмотров 453. Ответов 0

Доброго времени суток. Возникла задача - сохранить выходной поток с AVAudioEngine в файл. В интернете информации по этому поводу мало, единственное найденное решение было взято из темы на StackOverflow:

http://stackoverflow.com/questions/3...-unit-and-writ

И всё бы хорошо, но на iPad'е, а также при подключенных наушниках в этом методе в буфер лиcт AudioUnitRender записывает нули.

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- (OSStatus)renderToBufferList:(AudioBufferList *)bufferList
                   writeToFile:(ExtAudioFileRef)audioFile
                  bufferLength:(NSUInteger)bufferLength
                     timeStamp:(AudioTimeStamp *)timeStamp {
    [self clearBufferList:bufferList];
    AudioUnit outputUnit = self.engine.outputNode.audioUnit;
    OSStatus status =AudioUnitRender(outputUnit, 0, timeStamp, 0, (UInt32)bufferLength, bufferList);
    
 
    
    float *data1 = bufferList->mBuffers[0].mData;
    float *data2 = bufferList->mBuffers[1].mData;;
    
    for(int i=0; i<bufferLength/4; i++)
    {
        if(data1[i]!=0||data2[i]!=0)
        NSLog(@"%f - %f",data1[i],data2[i]);
    }
    
    if (status != noErr) {
        NSLog(@"Can not render audio unit");
        return status;
    }
    timeStamp->mSampleTime += bufferLength;
    status = ExtAudioFileWrite(audioFile, (UInt32)bufferLength, bufferList);
    if (status != noErr)
        NSLog(@"Can not write audio to file");
    return status;
}
99% вероятность, что это происходит из-за того что iPad имеет 2 выходных канала, но как исправить сложившуюся ситуацию непонятно.

Инициализация буфера:

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
AudioBufferList *AEAllocateAndInitAudioBufferList(AudioStreamBasicDescription audioFormat, int frameCount) {
    int numberOfBuffers = audioFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved ? audioFormat.mChannelsPerFrame : 1;
    int channelsPerBuffer = audioFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved ? 1 : audioFormat.mChannelsPerFrame;
    int bytesPerBuffer = audioFormat.mBytesPerFrame * frameCount;
    AudioBufferList *audio = malloc(sizeof(AudioBufferList) + (numberOfBuffers - 1) * sizeof(AudioBuffer));
    if (!audio) {
        return NULL;
    }
    audio->mNumberBuffers = numberOfBuffers;
    for (int i = 0; i < numberOfBuffers; i++) {
        if (bytesPerBuffer > 0) {
            audio->mBuffers[i].mData = calloc(bytesPerBuffer, 1);
            if (!audio->mBuffers[i].mData) {
                for (int j = 0; j < i; j++) free(audio->mBuffers[j].mData);
                free(audio);
                return NULL;
            }
        } else {
            audio->mBuffers[i].mData = NULL;
        }
        audio->mBuffers[i].mDataByteSize = bytesPerBuffer;
        audio->mBuffers[i].mNumberChannels = channelsPerBuffer;
    }
    return audio;
}
Основной метод, из которого вызываются вышеобозначенные:

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
- (NSString *)renderAudioAndWriteToFile {
    AVAudioOutputNode *outputNode = self.engine.outputNode;
    AudioStreamBasicDescription const *audioDescription = [outputNode outputFormatForBus:0].streamDescription;
    NSString *path = [self filePath];
    ExtAudioFileRef audioFile = [self createAndSetupExtAudioFileWithASBD:audioDescription andFilePath:path];
    if (!audioFile)
        return nil;
    AVURLAsset *asset = [AVURLAsset assetWithURL:self.file.url];
    NSTimeInterval duration = CMTimeGetSeconds(asset.duration);
    NSUInteger lengthInFrames = (NSUInteger) (duration * audioDescription->mSampleRate);
    
    const NSUInteger kBufferLength = 1024; //3756;
    
    AudioBufferList *bufferList = AEAllocateAndInitAudioBufferList(*audioDescription, kBufferLength);
    AudioTimeStamp timeStamp;
    memset (&timeStamp, 0, sizeof(timeStamp));
    timeStamp.mFlags = kAudioTimeStampSampleTimeValid;
    OSStatus status = noErr;
    for (NSUInteger i = kBufferLength; i < lengthInFrames; i += kBufferLength) {
        status = [self renderToBufferList:bufferList writeToFile:audioFile bufferLength:kBufferLength timeStamp:&timeStamp];
        if (status != noErr)
            break;
    }
    if (status == noErr && timeStamp.mSampleTime < lengthInFrames) {
        NSUInteger restBufferLength = (NSUInteger) (lengthInFrames - timeStamp.mSampleTime);
        AudioBufferList *restBufferList = AEAllocateAndInitAudioBufferList(*audioDescription, (Float32)restBufferLength);
        status = [self renderToBufferList:restBufferList writeToFile:audioFile bufferLength:restBufferLength timeStamp:&timeStamp];
        AEFreeAudioBufferList(restBufferList);
    }
    
    
    SInt64 fileLengthInFrames;
    UInt32 size = sizeof(SInt64);
    ExtAudioFileGetProperty(audioFile, kExtAudioFileProperty_FileLengthFrames, &size, &fileLengthInFrames);
    AEFreeAudioBufferList(bufferList);
    ExtAudioFileDispose(audioFile);
    if (status != noErr)
        [self showAlertWithTitle:@"Error" message:@"See logs for details"];
    else {
        NSLog(@"Finished writing to file at path: %@ \n File size must be %f Mb", path,(tmpData.length/1024.0)/1024.0);
        [self showAlertWithTitle:@"Success!" message:@"Now you can play a result file"];
    }
    return path;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2016, 15:41
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Сохранение в файл выходного потока из AVAudioEngine (Objective-C):

Сохранение потока данных в файл - Delphi
Здравствуйте. Помогите написать верный код для сохранения потока данных в файл, чтото я уже что только ен пробовал но верно у меня не...

Работа выходного потока - C++
Написал следующий код: template &lt;class Type&gt; class Stack { public: Stack(); void push(Type var); Type pop();

Контроль выходного потока данных 1С с помощью CISCO - Cisco
Подскажите пожалуйста как можно реализовать подсистему контроля выходного потока данных технологией CISCO. Так чтобы по сети передавались...

Сохранение файла на уровне потока - C++
Как из этой функции сохранения файла на уровне операционки сделать функцию сохранения файла на уровне потока? int Save(char* fileName,...

Сохранение звука с потока в Delphi. (Recording) - Delphi
Воспроизвожу несколько аудио одновременно. Используя фунцию mciSendString таким способом: mciSendString('Play D:\DrumPads\DEEP\1drum1.mp3...

Сохранение положения компонента на форме (Сохранение параметра в Ini-файл) - C++ Builder
Не знаю верно ли назвал тему. Доброго вечера тебе, всяк сюда входящий. Подскажите пожалуйста с вопросом: Имеется Form1, на нем...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.02.2016, 15:41
Привет! Вот еще темы с ответами:

Добавить к программе след действия: Сохранение и загрузка информации в текст. файл. Сохранение и загрузка информации в типизированный файл. - Pascal
Помогите добавить к программе след действия: Сохранение и загрузка информации в текст. файл. Сохранение и загрузка информации в...

При сохранение файла word (права доступа на сохранение ограничены) появляется пустой файл - MS Word
Добрый день! Проблема такая: Допустим есть пользователь, у которого ограничены права (может просматривать документ, но удалять и...

Считываю с потока файл пакетами -> сохраняю файл. что использовать на Qt вместо fwrite? - C++ Qt
пока программа не компилируется, успела только прописать вот такой код QString...

Нужно записать файл в поток так, чтобы файл из потока можно было передать по TCP - C#
Нужно записать файл в поток так, чтобы файл из потока можно было передать по TCP и открыть на сервере. И делать это все в безконечном цикле...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru