И картинки хранят в базе и аудиофайлы, и все работает пучком, назло злопыхателям 

 Поиск в аудифайлах - бред сивой кобылы, этим занимаются только силовики, и то сомневаюсь, так как тут нужен мощный ASR. Обычно ищут по номеру, имени и timestamp'у, который тут же в таблицу и добавляем. Хранится это дело в blob, имеет смысл добавить mime-тип файла, src/dst номер, timestamp. Алгоритм простой :
Пример dialplan'а:
...
[macro-start-record]
exten => s,1,Set(callrecord_fname=${CALLERID(num)}-${MACRO_EXTEN}-${EPOCH}.gsm)
exten => s,n,Set(callrecord_user=${ARG1})
exten => s,n,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)
exten => s,n,MixMonitor(${callrecord_fname},i(monitor_id))
....
exten => _1XX,Macro(start-record,${EXTEN})
same => n,Dial(SIP/${EXTEN})
exten => h,1,StopMixMonitor(${monitor_id})
exten => h,n,Agi(add_call_record.agi,${callrecord_fname},${callrecord_user})
...
Скелет AGI:
1. на входе имеем переменные callrecord_fname и callrecord_user
2. запихиваем /var/spool/asterisk/monitor/${callrecord_fname} бинарь в базу
3. удаляем нафик файл
На astxx это можно сделать в 20 строк, типа где-то так :
...
     astxx::agi& agi = astxx::agi::instance();
     string crf(string("/var/spool/asterisk/monitor/") + argv[1]);
     ifstream cr(crf.c_str(), ios::binary);
     if (!cr)
       throw Exception("acr.agi: Can't open CR file " + string(argv[1]) + " !");
     stringstream data;
     data << cr.rdbuf();
     if (!data.str().size()) {
       agi.verbose("acr.agi: Hmm, zero CR file !");
       unlink(crf.c_str());
       exit(0);
     }
     agi.verbose("acr.agi: Adding callrecord : " + string(argv[1]) + ", " +
       itoa(data.str().size()) + " bytes for " + string(argv[2]));
     db_query q;
     q << "insert into callrecords (...) values (..)";
     q.execute();
     unlink(crf.c_str());
...
Как наворот еще можно определять duration файла (через sox например) и добавлять его тоже - весьма удобственно рисовать это в табличке на фронтенде.