2010-02-24 8 views
2

J'utilise un encodeur lame pour convertir un wav en un mp3 en mac osx en utilisant l'objectif-c et le cacao. Je suis un débutant complet en matière d'encodage audio et mes compétences en C ne sont pas géniales. Peu importe ce que j'ai trébuché et est arrivé à l'étape de l'encodage réel, qui est où je suis coincé. Du code que j'ai étudié, il semble que je devrais utiliser lame_encode_buffer pour mono et lame_encode_buffer_interleaved pour stéréo (bien que le fait que le premier prenne des entrées pour les canaux gauche et droit me confond). Le code que j'ai jusqu'à présent est:EXC_BAD_ACCESS lors de l'appel de lame_encode_buffer

-(BOOL)encodeWave:(Wave *)wav { 
    if(![self loadLibrary]) { 
     return FALSE; 
    } 

    lame_set_num_channels(lgf,[wav channels]); 
    lame_set_in_samplerate(lgf,[wav sampleRate]); 
    lame_set_out_samplerate(lgf,[wav sampleRate]); 
    lame_set_brate(lgf, [wav getBrateInK]); 

    lame_init_params(lgf); 

    //encode stuff! 
    int total_samples = ([wav data_length]/[wav bytesPerSample]); 
    int n_samples = total_samples/[wav channels]; 
    Byte * inBuf = (Byte *)malloc([wav data_length]); 
    if(inBuf == NULL) 
     return FALSE; 
    memcpy(inBuf, [[wav data] bytes], [wav data_length]); 
    int outBuf_size = 7200 + (1.25*n_samples); 
    unsigned char * outBuf = (unsigned char *)malloc(outBuf_size); 
    if(outBuf == NULL) 
     return FALSE; 
    lame_encode_buffer(lgf,(short int *)inBuf,(short int *)inBuf, n_samples, outBuf, outBuf_size); 

    return TRUE; 

}

-(BOOL)loadLibrary { 

    NSString * pathToLib = [LAME_LIB_LIKELY_LOC stringByAppendingPathComponent:LAME_LIB_NAME]; 

    if(![[NSFileManager defaultManager] fileExistsAtPath:pathToLib]) 
     return FALSE; 

    void * lib_handle = dlopen("libmp3lame.dylib",RTLD_LOCAL|RTLD_LAZY); 
    if(!lib_handle) 
     return FALSE; 

    //Init 
    lgf = lame_init(); 

    //set error processor 
    lame_set_errorf(lgf,errorHandler); 
    lame_set_debugf(lgf,errorHandler); 
    lame_set_msgf(lgf,errorHandler); 


    return TRUE; 

}

Je l'ai utilisé le code de test sur inbuf pour imprimer toutes les données et il semble juste. Lorsque j'ai un point d'arrêt sur lame_encode_buffer, tous les paramètres sont affectés à leurs valeurs correctes (c'est-à-dire pas de pointeurs nuls).

Je suppose que c'est plus de moi en utilisant la mauvaise méthode ou en donnant le mauvais type d'entrée à la fonction, mais sans bonnes soluces sur ce disponible, je n'ai vraiment aucune idée.

Modifier (Backtrace)

#0 0x96e6ae42 in __kill() 
#1 0x96e6ae34 in kill$UNIX2003() 
#2 0x96edd23a in raise() 
#3 0x96ee9679 in abort() 
#4 0x96ede3db in __assert_rtn() 
#5 0x000938ca in convert_partition2scalefac_l (gfc=0x146ca000, eb=0xbfff3c38, thr=0xbfff3d3c, chn=0) at psymodel.c:498 
#6 0x00097c0b in L3psycho_anal_ns (gfp=0x877000, buffer=0xbfff8cac, gr_out=0, ms_ratio=0x146d6eb4, ms_ratio_next=0xbfffcb9c, masking_ratio=0xbfffd390, masking_MS_ratio=0xbfffcbf0, percep_entropy=0xbfffcbb0, percep_MS_entropy=0xbfffcba0, energy=0xbfffcbc8, blocktype_d=0xbfffac24) at psymodel.c:1712 
#7 0x00086fa0 in lame_encode_mp3_frame (gfp=0x877000, inbuf_l=0x146ca010, inbuf_r=0x146cde50, mp3buf=0x877800 "", mp3buf_size=9537) at encoder.c:374 
#8 0x0008a6e1 in lame_encode_frame (gfp=0x877000, inbuf_l=0x0, inbuf_r=0x0, mp3buf=0x0, mp3buf_size=0) at lame.c:1364 
#9 0x0008ab57 in lame_encode_buffer_sample_t (gfp=0x877000, buffer_l=0x146f5000, buffer_r=0x160c0000, nsamples=0, mp3buf=0x877800 "", mp3buf_size=9537) at lame.c:1541 
#10 0x0008ad6e in lame_encode_buffer (gfp=0x877000, buffer_l=0xbfffdcb0, buffer_r=0xbfffe5b0, nsamples=576, mp3buf=0x877800 "", mp3buf_size=9537) at lame.c:1591 
#11 0x0008ca3f in lame_encode_flush (gfp=0x877000, mp3buffer=0x877000 "\377\377\377\377\001", mp3buffer_size=9537) at lame.c:1869 
#12 0x00011d25 in -[MP3EncodingService encodeWave:] (self=0x1d96e0, _cmd=0x14c9f, wav=0x14712460) at /Users/tim/sp/MP3EncodingService.m:50 
#13 0x0000edfb in -[LibraryController convert:] (self=0x1887f0, _cmd=0x15046, sender=0x198480) at /Users/tim/sp/LibraryController.m:908 
#14 0x93a794cb in -[NSApplication sendAction:to:from:]() 
#15 0x93a79408 in -[NSControl sendAction:to:]() 
#16 0x93a7928e in -[NSCell _sendActionFrom:]() 
#17 0x93a788e7 in -[NSCell trackMouse:inRect:ofView:untilMouseUp:]() 
#18 0x93a7813a in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:]() 
#19 0x93a779f4 in -[NSControl mouseDown:]() 
#20 0x93a76133 in -[NSWindow sendEvent:]() 
#21 0x93a42cd9 in -[NSApplication sendEvent:]() 
#22 0x939a062f in -[NSApplication run]() 
#23 0x9396d834 in NSApplicationMain() 
#24 0x0000292c in main (argc=1, argv=0xbffff748) at /Users/tim/sp/main.m:13 
+0

Exécuter ce sous gdb - quand vous obtenez un accident puis utilisez la commande « bt » pour obtenir un backtrace. –

+0

Je l'ai ajouté. On ne voit vraiment rien d'utile là-dedans cependant. – Septih

+0

Est-ce que la solution fonctionne pour vous? Si oui, veuillez accepter. Sinon, dites-nous ce qui s'est passé après avoir suivi les points 1.2.3, afin que nous puissions vous donner plus d'aide. –

Répondre

2

Difficile à dire. Vous êtes probablement en train de dépasser un tableau. Comme il semble que votre tableau de sortie a la bonne longueur, c'est probablement le tableau d'entrée. Si vous avez de la chance, essayez simplement de donner n_samples/2 (parce que 2 == sizeof (short)) au lieu de n_samples comme argument à lame_encode_buffer.

Le vrai, sérieusement de trouver une solution à votre problème est:

  1. Recompiler votre bibliothèque boiteux avec des informations de débogage (en option -g au compilateur) afin que vous obtenez des informations de ligne utiles dans votre gdb backtrace.
  2. Ensuite, récupérez le backtrace gdb à nouveau, et voyez si vous pouvez dire d'où vient le segfault.
  3. Exécutez ceci sous valgrind, qui vous dira où l'accès illégal se produit (comme le segfault pourrait ne pas se produire sur le premier accès illégal).

Je parie qu'il a quelque chose à voir avec la longueur du tableau que vous passez, bien :)

+0

À droite, avec n_samples/2, il a initialement arrêté l'exception, mais a produit un fichier garbage mp3 - Il a ensuite cessé de fonctionner une fois le débogage activé. J'ai mis à jour le backtrace dans la publication d'origine avec des données de débogage dans - ce qui suggère que le problème se produit dans lame_encode_flush. Running sous valgrind suggère que les problèmes surviennent dans lame_encode_buffer avec quelques tailles de pointeurs invalides ("Ecriture invalide de taille 1 ") et plusieurs utilisations de variables indéfinies ("Saut ou déplacement conditionnel dépend de valeur (s) non initialisée (s)") avant meurt. – Septih

+0

Donc, ce n'est plus un segfault, c'est un échec d'assertion: apparemment, vous obtenez une somme négative de seuils dans convert_partition2scalefac_l, ce qui n'est certainement pas attendu. Êtes-vous sûr que vos données d'entrée sont dans le bon format? Une autre idée, en l'absence de bonne procédure: regardez beaucoup d'exemples en cherchant "lame_encode_buffer" dans Google codesearch (www.google.com/codesearch) –

+0

J'ai regardé beaucoup d'exemples de codesearch (bien que 8/10 des résultats sont la bibliothèque elle-même) et le thème récurrent est qu'il est difficile de discerner comment ils construisent leurs données d'entrée comme habituellement ces projets convertiront de nombreux formats en mp3, pas seulement wav. Je vais continuer à regarder de toute façon, merci pour l'aide au débogage. – Septih

Questions connexes