iOS SDK redarea tonurilor de atingere cu cadrul de instrumente audio

Bine ați venit în a șaptea tranșă din seria noastră despre cum să proiectați și să construiți o versiune a telefonului iOS? app. În acest tutorial, voi demonstra cum să redați tonul audio corespunzător pentru fiecare număr de pe tastatura telefonului.

Final Preview Preview

Acesta este un instantaneu al a ceea ce vom construi pe parcursul acestei serii:

Înainte de a începe?

Aceasta este o serie de mai multe părți concepută pentru a preda subiecte intermediare SDK pentru iOS. Conținutul va deveni tot mai complex pe măsură ce seria progresează. Dacă, în orice moment, vă veți pierde în urma acestei serii, este posibil să trebuiască să faceți un pas înapoi și să lucrați prin intermediul seriei noastre Aflați obiectivul-C sau seria noastră de dezvoltare SDK de la începutul iOS.

În ultimul tutorial din această serie, am demonstrat cum să inițiez efectiv un apel iPhone după apelarea unui număr pe tastatură și, de asemenea, modul de formatare a afișării numărului când un utilizator introduce o cifră. În acest tutorial, vom adăuga tonurile de apel promise la fiecare dintre butoanele 0 - 9.

Prezentarea generală a iOS audio

SDK-ul iOS este livrat cu mai multe cadre care oferă diverse metode de a reda clipuri audio și chiar de a genera audio pe loc. Apple Ghid de programare multimedia descrie scopul fiecărui cadru audio disponibil, după cum urmează:

  • Folosește Media Player cadru pentru a reda melodii, cărți audio sau podcasturi audio de la o bibliotecă iPod a utilizatorului?
  • Folosește AV Foundation framework pentru a reda și înregistra audio utilizând o interfață Obiectiv-C simplă?
  • Folosește Caseta de instrumente audio cadru pentru redarea audio cu capabilități de sincronizare, accesarea pachetelor de intrare audio, analiza fluxurilor audio, conversia formatelor audio și înregistrarea audio cu acces la pachetele individuale?
  • Folosește Structura unității audio pentru a vă conecta la și a utiliza plug-inuri de procesare audio?
  • Folosește Cadrul OpenAL pentru a oferi redare audio pozitivă în jocuri și alte aplicații. iOS acceptă OpenAL 1.1?

-Ghid de programare multimedia: Utilizarea audio

O întreagă serie de tutoriale ar putea fi dedicată fiecăruia dintre cadrele din lista de mai sus, dar este suficient să spunem că în scopul acestui tutorial vom folosi cadrul de instrumente Audio Toolbox datorită unei singure oferte: System Sound Services. Serviciile de sunet ale sistemului sunt o interfață de nivel C destinată redării unor efecte sonore de interfață scurtă a utilizatorului și a altor clipuri audio de 30 de secunde sau mai puțin.

Procesul de redare a unui clip audio cu System Sound Services cuprinde trei etape:

  1. Înregistrați un clip audio cu System Sound Services pentru redare în viitorul (nu mai îndepărtat)
  2. Primiți un ID de sunet sistem (SSID) care identifică în mod unic clipul audio înregistrat pe serverul de sunet al sistemului.
  3. Apelați serverul de sunet de sistem cu SSID-ul corespunzător pentru a începe redarea.

Restul acestui tutorial va implementa acest proces pentru a reda tonuri DTMF pre-înregistrate pentru cifrele tastaturii 0-9.

De ce folosim tonuri pre-înregistrate în loc să generăm frecvența adecvată pe loc? În esență, pentru a economisi timp și pentru a păstra acest tutorial mai accesibil prin evitarea matematicii implicate în funcțiile sinusoidale și generarea de frecvențe. Dacă doriți să mergeți în acest loc, veți găsi probabil următoarele articole la îndemână:

  • Semnal multi-frecvență cu semnal dual
  • Atingeți tastatura Tone
  • Undă sinusoidală
  • Forumurile iPhone Dev SDK: generați un semnal sonor

Chiar vrei să știi cum să generezi zgomotul? Dacă acest post primește cel puțin 10 comentarii care solicită un tutorial despre cum să creați fișiere audio de la zero până la 1 mai 2011, voi face o serie avansată de servere SDK pe acest subiect. Nu există promisiuni că va implica tonuri de atingere specifice DTMF, dar cu siguranță va fi ceva minunat.

Odată ce cunoștințele teoretice au ieșit din cale, hai să ne aruncăm în cod și să facem această facilitate!

Pasul 1: Importați cadrul AudioToolbox

Va trebui să începem prin importarea cadrului de instrumente audio în aplicația noastră, pentru a face sistemul de sunet de sistem la dispoziția codului nostru. Pentru a face acest lucru, selectați proiectul "PhoneAppSkin" din panoul Project Navigator din Xcode, apoi selectați "PhoneAppSkin" sub "TARGETS" și selectați în final fila "Build Fases". După aceasta, ecranul dvs. ar trebui să arate astfel:

Apoi, dați clic pe meniul derulant "Link Binary With Libraries" și faceți clic pe simbolul "+" pentru a adăuga un nou cadru la faza de legare a proiectului.

În cele din urmă, găsiți cadrul "AudioToolbox" în fereastra pop-up, apoi faceți clic pe "Adăugați".

Apoi, deschideți PhoneViewController.h fișier și adăugați linia necesară pentru a importa de fapt cadrul de instrumente Audio Tool în clasa dvs .:

 #import  #import 

Funcțiile din caseta de instrumente audio trebuie să fie acum accesibile pentru clasa dvs.!

Pasul 2: Importați fișierele WAV Tone Touch

Descărcați și deschideți codul sursă atașat la această postare Mobiletuts + și găsiți folderul intitulat "Audio". Glisați întregul dosar în folderul "Resurse" din Xcode Project Navigator, asigurându-vă că ați bifat opțiunea "Copiere" când vi se solicită. Ar trebui să ajungeți cu un ecran de felul următor:

Pasul 3: Creați o matrice pentru referințele SSID

În PhoneViewController.h, adăugați următoarea declarație de matrice în stil C:

 @interface PhoneViewController: UIViewController SystemSoundID toneSSIDs [10]; 

Linia 13 declară o matrice de tip C de tip SystemSoundID cu o capacitate maximă de 10.

Stocarea ID-urilor de sunet ale sistemului în acest câmp vă va permite să trimiteți rapid clipul audio corespunzător în numberButtonPressed: mai târziu.

Pasul 4: Înregistrați sunetele sistemului ton

Deschis PhoneViewController.m și săriți la initWithCoder metoda pe linia 17. Cand PhoneViewController este inițializată inițial și initWithCoder metoda este numită, vrem să înregistrăm sunete ale sistemului pentru fiecare ton care va fi folosit pe tastatură cu serverul de sunet al sistemului iOS. După ce un sunet este înregistrat pe serverul de sunet, putem instrui serverul să redea fișierul de sunet mai târziu când tastatura este apăsată.

Pentru a înregistra tonurile de atingere 0-9, adăugați următorul cod:

 -(id) initWithCoder: (NSCododer *) aDecoder auto = [super initWithCoder: aDecoder]; dacă (auto) phoneNumberString = [[NSString alloc] init]; pentru (int count = 0; count < 10; count++) NSString *toneFilename = [NSString stringWithFormat:@"DTMF_%02d", count]; NSURL *toneURLRef = [[NSBundle mainBundle] URLForResource:toneFilename withExtension:@"wav"]; SystemSoundID toneSSID = 0; AudioServicesCreateSystemSoundID( (CFURLRef) toneURLRef, &toneSSID ); toneSSIDs[count] = toneSSID;   return self; 

Pe linia 24, A pentru buclă care va repeta de 10 ori începe. Scopul acestui lucru pentru buclă este de a adăuga un nou ID de sistem de sunet la toneSSIDs pentru fiecare dintre tonurile de atingere asociate tastelor 0-9.

Pe linia 25, un exemplu de NSString este instanțiată care va păstra numele fișierului tonului DTMF relevant. O notă interesantă pe această linie este stringWithFormat: apelul metodic și % 02d formatul specificat. Acest specificator de format va converti orice cifră la o cifră cu cusături zero cu 2 caractere în lungime. De exemplu, 0 devine '00', 1 devine '01', 2 devine '02', etc.

Pe linia 27, NSBundle clasa este utilizată pentru a genera o cale de sistem de fișiere la numele de fișier generat pe linia 25 cu o extensie a "wav" atașată. NSLog această valoare dacă doriți să vedeți calea completă pentru dvs..

Linia 29 creează o variabilă care să dețină SystemSoundID care vor fi generate de serverul de sunet al sistemului iOS următor.

Ca o notă laterală, SystemSoundID este doar un typedef pentru Mac Type UInt32, care este el însuși un typedef pentru nesemnate lungi. În consecință, am fi putut declara variabila pe această linie de tip nesemnate lungi, dar acest lucru ar fi o practică proastă, deoarece viitoarele versiuni de iOS ar putea modifica SystemSoundID tip, cauzând ruperea codului. Cu toate acestea, este bine să țineți cont de acest lucru când lucrați SystemSoundIDdeoarece compilatorul va avertiza uneori despre incompatibilitate nesemnate lungi tipuri.

Linii 31 - 34 sunt un apel în funcție de stilul c AudioServicesCreateSystemSoundID, care ia o CFURL (URL-ul Fundației Fundației) a căii fișierului audio pentru a genera un ID de sistem de sunet și o referință SystemSoundID care va fi utilizată pentru stocarea SSID-ului după ce a fost creat. Observați cum apare caracterul ampersand (adică '&') înainte de toneSSID variabilă pe linia 33? Acesta este un operator prefix unar care convertește toneSSID parametru în adresa de memorie a variabilei în loc de valoarea stocată în memorie pentru acea variabilă. Acest lucru se face astfel încât AudioServicesCreateSystemSoundID funcția poate stoca numărul SSID generat direct în toneSSID adresă de memorie, permițând apelantului funcției (adică metoda noastră) accesul la SSID-ul generat, fără a trece, în realitate, SSID înapoi din funcție.

Sunați puțin confuz? Probabil va fi dacă nu sunteți deja experimentat în programare într-o limbă precum C, C ++ sau Go. Deoarece obiectivul C este o suprasetare strictă a limbajului C, SDK-ul iOS se bazează uneori pe bibliotecile scrise în procedură C. Dacă sintaxa C nu are sens pentru tine, nu-ți face griji prea mult acum, dar luați-o ca o provocare pentru a completa cunoștințele SDK-ului iOS cu fundamentele limbii C în viitor!

Pe linia 35, indicele toneSSIDs c-stil matrice desemnate de curent numara valoare este atribuită valoarea creată de AudioServicesCreateSystemSoundID funcţie. Această valoare SSID va fi menționată mai târziu pentru a reda tonul corespunzător atunci când utilizatorul interceptează numerele tastaturii.

Pasul 5: Redați sunetele de atingere la atingere

numberButtonPressed: metoda se numește de fiecare dată touchUpInside incendii eveniment pentru butoanele 0 - 9. Deoarece indicii 0-9 din toneSSIDs array conține acum tonul corespunzător pentru fiecare buton, următoarele trei linii de cod sunt suficiente pentru a reda tonul corespunzător:

 -(IBAction) numberButtonPressed: (UIButton *) apăsatButton int toneIndex = [presedButton.titleLabel.text intValue]; SystemSoundID: toneSSID = toneSSIDs [tonIndex]; AudioServicesPlaySystemSound (toneSSID); auto.phoneNumberString = [auto.phoneNumberString șirByAppendingString: pressedButton.titleLabel.text]; [self displayPhoneNumber]; 

Linia 96 convertește valoarea textului presat UIButton titlu la un număr întreg dintr-un șir.

Cu cifra de pe tastatură obținută, linia 97 preia a SystemSoundID de la toneSSIDs mulțime.

Pe linia 98, AudioServicesPlaySystemSound se numește cu SSID-ul recuperat pentru a începe redarea tonului tactil.

Asta e! Dă-i drumul și salva și construi proiectul acum, și ar trebui să găsiți că numerele tastaturii au efecte sonore!

Pasul 6: Faceți-l ușor

Există o mică problemă cu soluția actuală. Observi întârzierea dintre atingerea butonului și tonul generat? În partea a 6 a acestei serii, butoanele tastaturii au fost configurate pentru a declanșa touchUpInside acțiune. Această acțiune se declanșează după ce utilizatorul își îndepărtează degetul de pe buton. Cu toate acestea, tonul ar trebui să fie redat imediat ce utilizatorul apasă butonul, nu după ce își îndepărtează degetul. Pentru a rezolva acest lucru, deschideți-l PhoneView.xib, eliminați touchUpInside IBAction referințe pentru toate butoanele și apoi legarea fiecărui buton aterizare acțiune la adresa numberButtonPressed: metodă.

Dacă aveți nevoie de ajutor pentru a afla cum să faceți acest pas, consultați doar partea 6, Pasul 1 din această serie.

Învelire

Acest tutorial a fost un turneu de vârf al cadrului de instrumente audio și al sistemelor Sound System. Dacă aveți întrebări, nu ezitați să le lăsați în comentariile de mai jos și voi face tot ce pot pentru a răspunde. Desigur, nu sunt destule ore în timpul zilei pentru ca eu să-mi verific toate postările din trecut pentru comentarii noi în fiecare zi, așa că luni de zile poți avea mai mult noroc contactând-mă prin Twitter: @markhammonds.

Cod