/** * Initialize and get the instance of media endpoint. */ PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, unsigned worker_cnt, pjmedia_endpt **p_endpt) { pj_pool_t *pool; pjmedia_endpt *endpt; unsigned i; pj_status_t status; if (!error_subsys_registered) { pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, &pjmedia_strerror); error_subsys_registered = 1; } PJ_ASSERT_RETURN(pf && p_endpt, PJ_EINVAL); PJ_ASSERT_RETURN(worker_cnt <= MAX_THREADS, PJ_EINVAL); pool = pj_pool_create(pf, "med-ept", 512, 512, NULL); if (!pool) return PJ_ENOMEM; endpt = PJ_POOL_ZALLOC_T(pool, struct pjmedia_endpt); endpt->pool = pool; endpt->pf = pf; endpt->ioqueue = ioqueue; endpt->thread_cnt = worker_cnt; /* Sound */ status = pjmedia_aud_subsys_init(pf); if (status != PJ_SUCCESS) goto on_error; /* Init codec manager. */ status = pjmedia_codec_mgr_init(&endpt->codec_mgr); if (status != PJ_SUCCESS) goto on_error; /* Create ioqueue if none is specified. */ if (endpt->ioqueue == NULL) { endpt->own_ioqueue = PJ_TRUE; status = pj_ioqueue_create( endpt->pool, PJ_IOQUEUE_MAX_HANDLES, &endpt->ioqueue); if (status != PJ_SUCCESS) goto on_error; if (worker_cnt == 0) { PJ_LOG(4,(THIS_FILE, "Warning: no worker thread is created in" "media endpoint for internal ioqueue")); } } /* Create worker threads if asked. */ for (i=0; i<worker_cnt; ++i) { status = pj_thread_create( endpt->pool, "media", &worker_proc, endpt, 0, 0, &endpt->thread[i]); if (status != PJ_SUCCESS) goto on_error; } *p_endpt = endpt; return PJ_SUCCESS; on_error: /* Destroy threads */ for (i=0; i<endpt->thread_cnt; ++i) { if (endpt->thread[i]) { pj_thread_destroy(endpt->thread[i]); } } /* Destroy internal ioqueue */ if (endpt->ioqueue && endpt->own_ioqueue) pj_ioqueue_destroy(endpt->ioqueue); pjmedia_aud_subsys_shutdown(); pj_pool_release(pool); return status; }
static int main_func(int argc, char *argv[]) { pj_caching_pool cp; pj_pool_t *pool; int rc = 0; pj_status_t status = PJ_SUCCESS; if (argc != 2) { puts("Error: filename required"); puts(desc); return 1; } /* Must init PJLIB first: */ status = pj_init(); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); /* Must create a pool factory before we can allocate any memory. */ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); /* Create memory pool for our file player */ pool = pj_pool_create( &cp.factory, /* pool factory */ "AVI", /* pool name. */ 4000, /* init size */ 4000, /* increment size */ NULL /* callback on error */ ); pjmedia_video_format_mgr_create(pool, 64, 0, NULL); pjmedia_converter_mgr_create(pool, NULL); pjmedia_event_mgr_create(pool, 0, NULL); pjmedia_vid_codec_mgr_create(pool, NULL); status = pjmedia_vid_dev_subsys_init(&cp.factory); if (status != PJ_SUCCESS) goto on_return; status = pjmedia_aud_subsys_init(&cp.factory); if (status != PJ_SUCCESS) { goto on_return; } #if PJMEDIA_HAS_FFMPEG_VID_CODEC status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory); if (status != PJ_SUCCESS) goto on_return; #endif rc = aviplay(pool, argv[1]); /* * File should be playing and looping now */ /* Without this sleep, Windows/DirectSound will repeteadly * play the last frame during destroy. */ pj_thread_sleep(100); on_return: #if PJMEDIA_HAS_FFMPEG_VID_CODEC pjmedia_codec_ffmpeg_vid_deinit(); #endif pjmedia_aud_subsys_shutdown(); pjmedia_vid_dev_subsys_shutdown(); pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance()); pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance()); pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance()); pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance()); /* Release application pool */ pj_pool_release( pool ); /* Destroy pool factory */ pj_caching_pool_destroy( &cp ); /* Shutdown PJLIB */ pj_shutdown(); /* Done. */ return 0; }
PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory) { return pjmedia_aud_subsys_init(factory); }
/* Application init */ static pj_status_t app_init() { unsigned i, count; pj_status_t status; /* Redirect log */ pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer); pj_log_set_decor(PJ_LOG_HAS_NEWLINE); pj_log_set_level(3); /* Init pjlib */ status = pj_init(); if (status != PJ_SUCCESS) { app_perror("pj_init()", status); return status; } pj_caching_pool_init(&cp, NULL, 0); /* Init sound subsystem */ status = pjmedia_aud_subsys_init(&cp.factory); if (status != PJ_SUCCESS) { app_perror("pjmedia_snd_init()", status); pj_caching_pool_destroy(&cp); pj_shutdown(); return status; } count = pjmedia_aud_dev_count(); PJ_LOG(3,(THIS_FILE, "Device count: %d", count)); for (i=0; i<count; ++i) { pjmedia_aud_dev_info info; pj_status_t status; status = pjmedia_aud_dev_get_info(i, &info); pj_assert(status == PJ_SUCCESS); PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz", i, info.name, info.input_count, info.output_count, info.default_samples_per_sec)); unsigned j; /* Print extended formats supported by this audio device */ PJ_LOG(3, (THIS_FILE, " Extended formats supported:")); for (j = 0; j < info.ext_fmt_cnt; ++j) { const char *fmt_name = NULL; switch (info.ext_fmt[j].id) { case PJMEDIA_FORMAT_PCMA: fmt_name = "PCMA"; break; case PJMEDIA_FORMAT_PCMU: fmt_name = "PCMU"; break; case PJMEDIA_FORMAT_AMR: fmt_name = "AMR-NB"; break; case PJMEDIA_FORMAT_G729: fmt_name = "G729"; break; case PJMEDIA_FORMAT_ILBC: fmt_name = "ILBC"; break; case PJMEDIA_FORMAT_PCM: fmt_name = "PCM"; break; default: fmt_name = "Unknown"; break; } PJ_LOG(3, (THIS_FILE, " - %s", fmt_name)); } } /* Create pool */ pool = pj_pool_create(&cp.factory, THIS_FILE, 512, 512, NULL); if (pool == NULL) { app_perror("pj_pool_create()", status); pj_caching_pool_destroy(&cp); pj_shutdown(); return status; } /* Init delay buffer */ status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE, SAMPLES_PER_FRAME, CHANNEL_COUNT, 0, 0, &delaybuf); if (status != PJ_SUCCESS) { app_perror("pjmedia_delay_buf_create()", status); //pj_caching_pool_destroy(&cp); //pj_shutdown(); //return status; } return PJ_SUCCESS; }
int main() { pj_caching_pool cp; pj_bool_t done = PJ_FALSE; pj_status_t status; /* Init pjlib */ status = pj_init(); PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1); pj_log_set_decor(PJ_LOG_HAS_NEWLINE); /* Must create a pool factory before we can allocate any memory. */ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); status = pjmedia_aud_subsys_init(&cp.factory); if (status != PJ_SUCCESS) { app_perror("pjmedia_aud_subsys_init()", status); pj_caching_pool_destroy(&cp); pj_shutdown(); return 1; } list_devices(); while (!done) { char line[80]; print_menu(); if (fgets(line, sizeof(line), stdin)==NULL) break; switch (line[0]) { case 'l': list_devices(); break; case 'R': pjmedia_aud_dev_refresh(); puts("Audio device list refreshed."); break; case 'i': { unsigned dev_index; if (sscanf(line+2, "%u", &dev_index) != 1) { puts("error: device ID required"); break; } show_dev_info(dev_index); } break; case 't': { pjmedia_dir dir; int rec_id, play_id; unsigned clock_rate, ptime, chnum; int cnt; cnt = sscanf(line+2, "%d %d %u %u %u", &rec_id, &play_id, &clock_rate, &ptime, &chnum); if (cnt < 4) { puts("error: not enough parameters"); break; } if (clock_rate < 8000 || clock_rate > 128000) { puts("error: invalid clock rate"); break; } if (ptime < 10 || ptime > 500) { puts("error: invalid ptime"); break; } if (cnt==5) { if (chnum < 1 || chnum > 4) { puts("error: invalid number of channels"); break; } } else { chnum = 1; } if (rec_id >= 0 && rec_id < (int)dev_count) { if (play_id >= 0 && play_id < (int)dev_count) dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; else dir = PJMEDIA_DIR_CAPTURE; } else if (play_id >= 0 && play_id < (int)dev_count) { dir = PJMEDIA_DIR_PLAYBACK; } else { puts("error: at least one valid device index required"); break; } test_device(dir, rec_id, play_id, clock_rate, ptime, chnum); } break; case 'r': /* record */ { int index; char filename[80]; int count; count = sscanf(line+2, "%d %s", &index, filename); if (count==1) record(index, NULL); else if (count==2) record(index, filename); else puts("error: invalid command syntax"); } break; case 'p': /* playback */ { int index; char filename[80]; int count; count = sscanf(line+2, "%d %s", &index, filename); if (count==1) play_file(index, NULL); else if (count==2) play_file(index, filename); else puts("error: invalid command syntax"); } break; case 'd': /* latencies */ { int rec_lat, play_lat; if (sscanf(line+2, "%d %d", &rec_lat, &play_lat) == 2) { capture_lat = (unsigned) (rec_lat>=0? rec_lat:PJMEDIA_SND_DEFAULT_REC_LATENCY); playback_lat = (unsigned) (play_lat >= 0? play_lat : PJMEDIA_SND_DEFAULT_PLAY_LATENCY); printf("Recording latency=%ums, playback latency=%ums", capture_lat, playback_lat); } else { printf("Current latencies: record=%ums, playback=%ums", capture_lat, playback_lat); } puts(""); } break; case 'v': if (pj_log_get_level() <= 3) { pj_log_set_level(5); puts("Logging set to detail"); } else { pj_log_set_level(3); puts("Logging set to quiet"); } break; case 'q': done = PJ_TRUE; break; } } pj_caching_pool_destroy(&cp); pj_shutdown(); return 0; }
pj_status_t latency_checker::start(latency_config_t &config) { pj_status_t result = PJ_EINVAL; if(m_pool == NULL) { m_dstate = 0; m_start_tone_time.u64 = 0; m_latency = 0; m_quality = 0; m_config = config; m_status_string[0] = 0; m_gain = new snd_agc("",30,1,32000,32000); m_idle_freq1_det = new tone_detector(m_config.clock_rate,IDLE_FREQ1); m_idle_freq2_det = new tone_detector(m_config.clock_rate,IDLE_FREQ2); m_active_freq1_det = new tone_detector(m_config.clock_rate,ACTIVE_FREQ1); m_active_freq2_det = new tone_detector(m_config.clock_rate,ACTIVE_FREQ2); init_generate_dual_tone(&m_idle_tone,m_config.clock_rate,IDLE_FREQ1,IDLE_FREQ2,32767); init_generate_dual_tone(&m_active_tone,m_config.clock_rate,ACTIVE_FREQ1,ACTIVE_FREQ2,32767); pj_log_set_level(0); pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_SENDER | PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC); if(pj_init()==PJ_SUCCESS) { m_caching_pool = (pj_caching_pool *)malloc(sizeof(pj_caching_pool)); pj_caching_pool_init( m_caching_pool, NULL, 0 ); m_pool_factory=&m_caching_pool->factory; m_pool = pj_pool_create(m_pool_factory, "LATENCY NATIVE", 4000, 4000, NULL); pj_log_set_level(m_config.logs.level); pj_logging_init(m_pool); pj_logging_setLogToConsole(1); pj_logging_setFilename(m_config.logs.file_name); pj_logging_setMaxLogFiles(m_config.logs.max_files); pj_logging_setMaxLogFileSize(m_config.logs.max_file_size*1024*1024); pj_logging_start(); pj_get_timestamp(&m_last_get_frame_time); m_lock = new PPJ_SemaphoreLock(m_pool,NULL,1,1); pjmedia_aud_subsys_init(m_pool_factory); #if PJMEDIA_AUDIO_DEV_HAS_ANDROID #if PJ_ANDROID_DEVICE==1 pjmedia_aud_register_factory(&pjmedia_android_factory); #endif #if PJ_ANDROID_DEVICE==2 pjmedia_aud_register_factory(&pjmedia_opensl_factory); #endif #if PJ_ANDROID_DEVICE==3 pjmedia_aud_register_factory(&pjmedia_alsa_factory); #endif #endif pjmedia_aud_param params; params.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK; params.rec_id = 1; params.play_id = 6; params.clock_rate = m_config.clock_rate; params.channel_count = 1; params.samples_per_frame = m_config.min_frame_length*m_config.clock_rate/1000; params.bits_per_sample = 16; params.flags = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY | PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY; params.input_latency_ms = m_config.min_frame_length; params.output_latency_ms = m_config.min_frame_length; result = pjmedia_aud_stream_create(¶ms,&rec_cb_s,&play_cb_s,this,&m_aud_stream); if(result==PJ_SUCCESS) { result = pjmedia_aud_stream_start(m_aud_stream); if(result==PJ_SUCCESS) { } } } } if(result!=PJ_SUCCESS) internal_clean(); return result; }