2012-05-17 11 views
5

Pracuję nad projektem VoIP na iOS. Zgodnie z sugestią dokumentów firmy Apple używam urządzenia dźwiękowego VoiceProcessingIO, aby uzyskać wsparcie na anulowanie echa.Użyj urządzenia audio IO do przetwarzania głosu w iOS

Ponieważ moja aplikacja wymaga oddzielnych operacji po stronie renderowania i przechwytywania (na przykład, wyłączenie głośnika, ale pozwól mikrofonowi kontynuować), tworzę dwie jednostki audio, jedną zamykam port przechwytywania, a drugą zamykam port renderowania.

Obecny kod działa dobrze, dopóki nie dowiem się, jak działa usuwanie echa: wymaga porównania sygnałów z mikrofonu i głośnika. Więc moim zmartwieniem jest: czy można bezpiecznie używać dwóch urządzeń do przetwarzania głosu, takich jak moje podejście? Ponadto, ponieważ anulowanie dźwięku działa głównie po stronie przechwytywania, czy możliwe jest użycie urządzenia audio RemoteIO do renderowania (połączenie z głośnikiem)?

Nie jestem w 100% pewny, ponieważ wkraczam na krótko do tego obszaru. Próbowałem także od developer.apple.com, ale wszystkie przykłady znalezione na developer.apple.com zazwyczaj używają tylko jednej jednostki audio.

Czy ktoś może dać wskazówki? Czy moje podejście ma potencjalny wpływ na funkcje urządzenia VoiceProcessingIO?

Dzięki Fuzhou

Odpowiedz

1

Po pierwsze, VoiceProcessingIO jest (jak mnie pisanie tego) tylko tłumienie echa, nie echa. Zasadniczo po prostu wyłącza wejście, jeśli wyjście jest zbyt głośne. Oznacza to, że np. w połączeniu VoIP, drugi koniec nie będzie w stanie usłyszeć cię podczas rozmowy. Pełne anulowanie echa pozostawiłoby wejście włączone, ale próbowało odjąć echa wyjścia.

Proponuję tylko przy użyciu jednego urządzenia i samodzielnie obsłużyć obudowę głośnika wyłączającego. Twój wyjściowy oddzwonienie może wyglądać następująco:

OSStatus output_callback(
    void *inRefCon, 
    AudioUnitRenderActionFlags *ioActionFlags, 
    const AudioTimeStamp  *inTimeStamp, 
    UInt32      inInputBusNumber, 
    UInt32      inNumberFrames, 
    AudioBufferList    *ioData) 
{ 
    my_context_t *context = inRefCon; 
    audio_sample_t *dst = (audio_sample_t *)ioData->mBuffers[0].mData; 

    if (context->muted) { 
    memset(dst, 0, inNumberFrames * sizeof(audio_sample_t)); 
    } else { 
    get_output_samples(context, dst, inNumberFrames); 
    } 
    return noErr; 
} 

Dawanie milczenia, by tłumić echo, nie powinno mieć na niego negatywnego wpływu.