Пример #1
0
int gavf_start(gavf_t * g)
{
    if(!g->wr || g->streams)
        return 1;

    g->sync_distance = g->opt.sync_distance;

    init_streams(g);

    gavf_footer_init(g);

    if(g->ph.num_streams == 1)
    {
        g->encoding_mode = ENC_SYNCHRONOUS;
        g->final_encoding_mode = ENC_SYNCHRONOUS;
    }
    else
    {
        g->encoding_mode = ENC_STARTING;

        if(g->opt.flags & GAVF_OPT_FLAG_INTERLEAVE)
            g->final_encoding_mode = ENC_INTERLEAVE;
        else
            g->final_encoding_mode = ENC_SYNCHRONOUS;
    }

    if(g->opt.flags & GAVF_OPT_FLAG_DUMP_HEADERS)
        gavf_program_header_dump(&g->ph);

    if(!gavf_program_header_write(g->io, &g->ph))
        return 0;

    return 1;
}
Пример #2
0
init_clips()
  {
   init_streams();        /* Initalizes streams for I/O.       */
   sysdep_inits();        /* System dependent initializations. */   
#if DEFFACTS_CONSTRUCT
   set_up_deffacts();
#endif
  }
Пример #3
0
 CmdOptions(const CmdArgsList& cmd, const char* cd = NULL, const char** env = NULL,
            int user = INT_MAX, int nice = INT_MAX, int group = INT_MAX)
     : m_shell(true), m_pty(false), m_cmd(cmd), m_cd(cd ? cd : "")
     , m_kill_timeout(KILL_TIMEOUT_SEC)
     , m_kill_group(false)
     , m_cenv(NULL), m_nice(INT_MAX)
     , m_group(group), m_user(user)
 {
     init_streams();
 }
Пример #4
0
 CmdOptions()
     : m_tmp(0, 256), m_shell(true), m_pty(false)
     , m_kill_timeout(KILL_TIMEOUT_SEC)
     , m_kill_group(false)
     , m_cenv(NULL), m_nice(INT_MAX)
     , m_group(INT_MAX), m_user(INT_MAX)
     , m_success_exit_code(0)
 {
     init_streams();
 }
Пример #5
0
static int handle_chunk(gavf_t * g, char * sig)
{
    if(!strncmp(sig, GAVF_TAG_PROGRAM_HEADER, 8))
    {
        if(!gavf_program_header_read(g->io, &g->ph))
            return 0;

        init_streams(g);
    }
    else if(!strncmp(sig, GAVF_TAG_SYNC_HEADER, 8))
    {
        g->first_sync_pos = g->io->position;
    }
    return 1;
}
Пример #6
0
init_clips()
  {
   init_streams();        /* Initalizes streams for I/O.       */
   init_symbol_table();   /* Initializes the hash table.       */
   sysdep_inits();        /* System dependent initializations. */
   sysfctns();            /* Define system functions.          */
   define_commands();     /* Define user interface functions.  */
   mathfctns();           /* Define math package functions.    */
   usrfuncs();            /* Define user functions.            */
#if (! BLOAD_ONLY)
   init_constructs();     /* Initializes constructs.           */
#endif
#if DEFFACTS_CONSTRUCT
   set_up_deffacts();
#endif
#if DEFTEMPLATES && (! BLOAD_ONLY)
   SetupDeftemplates();
#endif
   init_gen_ptrs();       /* Initializes function pointers.    */
   init_exprn_psr();      /* Initializes expression parsers.   */
  }
Пример #7
0
static int init(struct repeater *repeater, struct repeater_config *config)
{
    int status;

    repeater_init(repeater, config);

    /* Configure the bladeRF */
    status = init_device(repeater, config);
    if (status < 0) {
        fprintf(stderr, "Failed to initialize device.\n");
        return -1;
    }

    /* Allocate streams */
    status = init_streams(repeater, config);
    if (status < 0) {
        fprintf(stderr, "Failed to allocate streams.\n");
        return -1;
    }

    return 0;
}
Пример #8
0
static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
{
	AVOutputFormat *output_format;
	int ret;

	output_format = av_guess_format(NULL, ffm->params.file, NULL);
	if (output_format == NULL) {
		printf("Couldn't find an appropriate muxer for '%s'\n",
				ffm->params.file);
		return FFM_ERROR;
	}

	ret = avformat_alloc_output_context2(&ffm->output, output_format,
			NULL, NULL);
	if (ret < 0) {
		printf("Couldn't initialize output context: %s\n",
				av_err2str(ret));
		return FFM_ERROR;
	}

	ffm->output->oformat->video_codec = AV_CODEC_ID_NONE;
	ffm->output->oformat->audio_codec = AV_CODEC_ID_NONE;

	if (!init_streams(ffm)) {
		free_avformat(ffm);
		return FFM_ERROR;
	}

	ret = open_output_file(ffm);
	if (ret != FFM_SUCCESS) {
		free_avformat(ffm);
		return ret;
	}

	return FFM_SUCCESS;
}
Пример #9
0
int main (int argc, char **argv)

{
char		command [CMD_SIZE];

int		initialize_tape = 1;
int	 	tape_status = 5;

int		status;
unsigned char	*beam_ptr;
int		first_time = TRUE;

LL_beam_rec *enet_pak;

extern process_exit();
extern print_target_elev ();

	
	/* trap signals */
	(void) signal (SIGINT, ((void (*) ()) process_exit));
	(void) signal (SIGHUP, ((void (*) ()) process_exit));
	(void) signal (SIGTERM, ((void (*) ()) process_exit));

	enet_pak = (LL_beam_rec *) malloc ((unsigned) sizeof (LL_beam_rec));
	if (enet_pak == NULL)
	{
		(void) printf ("Malloc error \n");
		return (-1);
	}

	if ((!get_params (&Glob)))
		exit (2);

	/* initialize streams (fmq and/or shmem)  for sending beam data */
	if (init_streams ())
	{
		(void) fprintf (stderr, "streams initialization error");
		return (1);
	}

	if (system ("clear") != 0)
		perror ("clear");

/* 	Determine the source of the data to be reformatted */
	if (!Glob.real_time)
	{
		/* initialize the shared memory for receiving commands*/
    		if (recv_cmd (1, Glob.cmd_shmem_key, (unsigned char **) &command) == -1)
		{
			(void) printf ("recv_cmd fatal error\n");
			exit (-1);
		}

		for (;;)
		{
			if ((status = get_shm_cmd (command)) > 0)
				break;
			else
				if (first_time)
				{
					first_time = FALSE;
					(void) printf ("waiting for menu process to send start command\n");
				}
				sleep (2);
		}
		source = parse_settings (command, &Glob);
		if (source < 0)
			return (0);
	}
	else
		source = RADAR;

	switch (source)
	{
	case RADAR: 

		if (recv_shm (1, Glob.input_shmem_key, &beam_ptr))
		{
			(void) printf ("recv_shm fatal error\n");
			exit (-1);
		}

		for (;go ;)
		{
			if (get_shmem_data (enet_pak, Glob.input_shmem_key)
																		== 0)
			{
				if (first_time)
				{
					(void) printf ("waiting for data\n");
					first_time = FALSE;
				}
				usleep (no_packet);
			}

			/* Check for a stop command */
			if (!Glob.real_time)
			{
				if ((status = get_shm_cmd (command)) > 0)
				{
					source = parse_settings (command, &Glob);
					if (source < 0) go = 0;
					if (source == FLAG_CHANGE)
					{
						(void) printf ("\n  Flag status: Dealias failure = %s\n",
											Glob.caf ? "TRUE":"FALSE");
						(void) printf ("                 Point Target    = %s\n",
											Glob.ctf ? "TRUE":"FALSE");
						(void) printf ("                SNR thresholding = %s\n",
											Glob.cvf ? "TRUE":"FALSE");
						(void) printf ("                 Clutter = %s\n",
											Glob.ccv ? "TRUE":"FALSE");
						(void) printf ("              low PRF in valid gate = %s\n\n",
											Glob.cv ? "TRUE":"FALSE");
					}

				}
			}
		}
		break;

	case TAPE:

		if (Glob.remote_tape)
		{
			if (tape_init (&fd_tape, Glob.tape_device))
			{
				(void) printf("Error initializing the tape device %s", 
														Glob.tape_device);
				source = -1;
				return (0);
			}
		}

		for (;go ;)
		{
			if (initialize_tape)
			{
				initialize_tape = FALSE;
				tape_command ();
			}

			tape_status = get_tape_data (fd_tape, data_rate, enet_pak); 
			switch (tape_status)
			{
                case 0:
					/* automatically rewind the tape
					 * when end of tape is detected
					 */
					 /*
                        		tape_rewind = REWIND;
		                        initialize_tape = TRUE;
					  */
					  /* or stop the system at the end of the tape */
                    (void) printf ("Received STOP command \n");
		            go = 0;
					exit (0);
               		break;

                case INITIALIZE_RMT:
					(void) close (fd_tape);
					if (tape_init (&fd_tape, Glob.tape_device))
					{
						(void) printf("Error initializing the tape device %s", 
														Glob.tape_device);
						source = -1;
						return (0);
					}
               		break;
                case INITIALIZE:
                    initialize_tape = TRUE;
               		break;
		        case REWIND:
		            /*go = 0;
					exit (0);
               		break;*/
                    tape_rewind = REWIND;
		            initialize_tape = TRUE;
               		break;
               	case TAPE_ERR: 
                	(void) printf ("Tape read error / received STOP command \n");
		             go = 0;
               		break;
				case RATE_CHANGE:
					initialize_tape = FALSE;
					break;

				case PAUSE:
					for (;;)
					{
						if (Glob.remote_tape)
						{
							(void) rmt_close ();
						}
						if ((status = get_shm_cmd (command)) > 0)
						{
							if (Glob.remote_tape)
							{
								if (tape_init (&fd_tape, Glob.tape_device))
								{
									(void) printf("Error initializing the tape device %s", Glob.tape_device);
									go = 0;
								}
							}
							break;
						}
						else
							usleep (3000);
					}
					break;
				case FLAG_CHANGE:
					(void) printf ("\n  Flag status: Dealias failure = %s\n",
										Glob.caf ? "TRUE":"FALSE");
					(void) printf ("                 Point Target    = %s\n",
										Glob.ctf ? "TRUE":"FALSE");
					(void) printf ("                SNR thresholding = %s\n",
										Glob.cvf ? "TRUE":"FALSE");
					(void) printf ("                 Clutter = %s\n",
										Glob.ccv ? "TRUE":"FALSE");
					(void) printf ("              low PRF in valid gate = %s\n\n",
										Glob.cv ? "TRUE":"FALSE");
			}
		}
		break;

	default:
			(void) printf ("source unrecognized \n");
			break;
	}

	return (0);

}
Пример #10
0
static pj_status_t factory_create_streamBDIMAD(pjmedia_aud_dev_factory *f,
                                    const pjmedia_aud_param *param,
                                    pjmedia_aud_rec_cb rec_cb,
                                    pjmedia_aud_play_cb play_cb,
                                    void *user_data,
                                    pjmedia_aud_stream **p_aud_strm)
{
    struct bd_factory *wf = (struct bd_factory*)f;
    pj_pool_t *pool;
    struct bd_stream *strm;
    pj_uint8_t silence_char;
    pj_status_t status;

    switch (param->ext_fmt.id) {
    case PJMEDIA_FORMAT_L16:
	silence_char = '\0';
	break;
    default:
	return PJMEDIA_EAUD_BADFORMAT;
    }

    /* Create and Initialize stream descriptor */
    pool = pj_pool_create(wf->pf, "BDIMAD_STREAM", 1000, 1000, NULL);
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);

    strm = PJ_POOL_ZALLOC_T(pool, struct bd_stream);
    pj_memcpy(&strm->param, param, sizeof(*param));
    strm->pool = pool;
    strm->rec_cb = rec_cb;
    strm->play_cb = play_cb;
    strm->user_data = user_data;
    strm->fmt_id = (pjmedia_format_id)param->ext_fmt.id;
    strm->silence_char = silence_char;
    strm->channel_count = param->channel_count;
    strm->samples_per_frame = param->samples_per_frame;

    if (param->dir & PJMEDIA_DIR_CAPTURE_PLAYBACK) {
        status = init_streams(wf, strm, param);

        if (status != PJ_SUCCESS) {
            stream_destroyBDIMAD(&strm->base);
            return status;
        }
    } else {
        stream_destroyBDIMAD(&strm->base);
        return PJMEDIA_EAUD_ERR;
    }

    strm->rec_buf = (pj_int16_t*)pj_pool_alloc(pool, 
		    strm->bytes_per_frame);
    if (!strm->rec_buf) {
        pj_pool_release(pool);
        return PJ_ENOMEM;
    }
    strm->rec_buf_count = 0;

    strm->play_buf = (pj_int16_t*)pj_pool_alloc(pool, 
		     strm->bytes_per_frame);
    if (!strm->play_buf) {
        pj_pool_release(pool);
        return PJ_ENOMEM;
    }
    strm->play_buf_count = 0;

    /* Apply the remaining settings */
    if(param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {
        stream_set_capBDIMAD(&strm->base, 
			     PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 
			     &param->output_vol);
    }
    if(param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING) {
        stream_set_capBDIMAD(&strm->base, 
			     PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING, 
			     &param->input_vol);
    }
    if(param->flags & PJMEDIA_AUD_DEV_CAP_EC) {
        stream_set_capBDIMAD(&strm->base, 
			     PJMEDIA_AUD_DEV_CAP_EC, 
			     &param->ec_enabled);
    }

    strm->base.op = &stream_op;
    *p_aud_strm = &strm->base;

    return PJ_SUCCESS;
}
Пример #11
0
bool Event_channel_hit_process(
        Channel* ch,
        Device_states* dstates,
        const Master_params* master_params,
        const Event_params* params)
{
    rassert(ch != NULL);
    rassert(ch->audio_rate > 0);
    rassert(ch->tempo > 0);
    rassert(dstates != NULL);
    rassert(master_params != NULL);
    rassert(params != NULL);
    rassert(params->arg != NULL);
    rassert(params->arg->type == VALUE_TYPE_INT);

    // Move the old Voices to the background
    Event_channel_note_off_process(ch, dstates, master_params, NULL);

    // Find our audio unit
    Audio_unit* au = Module_get_au_from_input(ch->parent.module, ch->au_input);
    if (au == NULL)
        return true;

    init_force_controls(ch, master_params);

    // Don't attempt to hit effects
    if (Audio_unit_get_type(au) != AU_TYPE_INSTRUMENT)
        return true;

    const int hit_index = (int)params->arg->value.int_type;

    if (!Audio_unit_get_hit_existence(au, hit_index))
        return true;

    const Param_proc_filter* hpf = Audio_unit_get_hit_proc_filter(au, hit_index);

    // Generate our next note random seed here so that random generation
    // is consistent even if we run out of voices
    const uint64_t note_rand_seed = Random_get_uint64(&ch->rand);

    // Find reserved voices
    Voice_group* vgroup = VOICE_GROUP_AUTO;

    if (!Voice_group_reservations_get_clear_entry(
                ch->voice_group_res, ch->num, &ch->fg_group_id) ||
            (Voice_pool_get_group(ch->pool, ch->fg_group_id, vgroup) == NULL))
    {
        reset_channel_voices(ch);
        return true;
    }

    int voice_index = 0;

    for (int i = 0; i < KQT_PROCESSORS_MAX; ++i)
    {
        const Processor* proc = Audio_unit_get_proc(au, i);
        if (proc == NULL ||
                !Device_is_existent((const Device*)proc) ||
                !Processor_get_voice_signals(proc))
            continue;

        // Skip processors that are filtered out for this hit index
        if ((hpf != NULL) && !Param_proc_filter_is_proc_allowed(hpf, i))
            continue;

        const Proc_state* proc_state = (Proc_state*)Device_states_get_state(
                dstates, Device_get_id((const Device*)proc));

        Voice_state_get_size_func* get_vstate_size =
            proc_state->parent.device->dimpl->get_vstate_size;
        if ((get_vstate_size != NULL) && (get_vstate_size() == 0))
            continue;

        char context_str[16] = "";
        snprintf(context_str, 16, "np%hd", (short)i);
        Random* random = Random_init(RANDOM_AUTO, context_str);
        Random_set_seed(random, note_rand_seed);
        const uint64_t voice_rand_seed = Random_get_uint64(random);

        Voice* voice = Voice_group_get_voice(vgroup, voice_index);

        const bool voice_allocated = init_voice(
                ch, voice, au, ch->fg_group_id, proc_state, i, voice_rand_seed);
        if (!voice_allocated)
        {
            // Some of our voices were reallocated
            reset_channel_voices(ch);
            return true;
        }

        ++voice_index;

        Voice_state* vs = voice->state;
        vs->hit_index = hit_index;

        if (vs->proc_type == Proc_type_force)
        {
            Force_controls* fc = Force_vstate_get_force_controls_mut(vs);
            Force_controls_copy(fc, &ch->force_controls);
        }
    }

    Channel_reset_test_output(ch);

    init_streams(ch, au);

    return true;
}
Пример #12
0
bool Event_channel_note_on_process(
        Channel* ch,
        Device_states* dstates,
        const Master_params* master_params,
        const Event_params* params)
{
    rassert(ch != NULL);
    rassert(ch->audio_rate > 0);
    rassert(ch->tempo > 0);
    rassert(dstates != NULL);
    rassert(master_params != NULL);
    rassert(params != NULL);
    rassert(params->arg != NULL);
    rassert(params->arg->type == VALUE_TYPE_FLOAT);

    // Move the old Voices to the background
    Event_channel_note_off_process(ch, dstates, master_params, NULL);

    // Find our audio unit
    Audio_unit* au = Module_get_au_from_input(ch->parent.module, ch->au_input);
    if (au == NULL)
        return true;

    double pitch_param = params->arg->value.float_type;

    // Retune pitch parameter if a retuner is active
    {
        const int tuning_index = master_params->cur_tuning_state;
        if (0 <= tuning_index && tuning_index < KQT_TUNING_TABLES_MAX)
        {
            Tuning_state* state = master_params->tuning_states[tuning_index];
            const Tuning_table* table =
                Module_get_tuning_table(master_params->parent.module, tuning_index);
            if (state != NULL && table != NULL)
                pitch_param = Tuning_state_get_retuned_pitch(state, table, pitch_param);
        }
    }

    if (ch->carry_pitch)
    {
        if (isnan(ch->pitch_controls.pitch))
            ch->pitch_controls.pitch = pitch_param;
        if (isnan(ch->pitch_controls.orig_carried_pitch))
            ch->pitch_controls.orig_carried_pitch = pitch_param;

        const double pitch_diff = pitch_param - ch->pitch_controls.orig_carried_pitch;
        ch->pitch_controls.pitch_add = pitch_diff;
    }
    else
    {
        Pitch_controls_reset(&ch->pitch_controls);
        ch->pitch_controls.orig_carried_pitch = pitch_param;

        Slider_set_tempo(&ch->pitch_controls.slider, master_params->tempo);
        Slider_set_length(&ch->pitch_controls.slider, &ch->pitch_slide_length);

        LFO_set_tempo(&ch->pitch_controls.vibrato, master_params->tempo);
        LFO_set_speed_slide(&ch->pitch_controls.vibrato, &ch->vibrato_speed_slide);
        LFO_set_depth_slide(&ch->pitch_controls.vibrato, &ch->vibrato_depth_slide);

        ch->pitch_controls.pitch = pitch_param;
        if (isnan(ch->pitch_controls.orig_carried_pitch))
            ch->pitch_controls.orig_carried_pitch = pitch_param;
    }

    init_force_controls(ch, master_params);

    // Don't attempt to play effects
    if (Audio_unit_get_type(au) != AU_TYPE_INSTRUMENT)
        return true;

    // Generate our next note random seed here so that random generation
    // is consistent even if we run out of voices
    const uint64_t note_rand_seed = Random_get_uint64(&ch->rand);

    // Find reserved voices
    Voice_group* vgroup = VOICE_GROUP_AUTO;

    if (!Voice_group_reservations_get_clear_entry(
                ch->voice_group_res, ch->num, &ch->fg_group_id) ||
            (Voice_pool_get_group(ch->pool, ch->fg_group_id, vgroup) == NULL))
    {
        reset_channel_voices(ch);
        return true;
    }

    int voice_index = 0;

    for (int i = 0; i < KQT_PROCESSORS_MAX; ++i)
    {
        const Processor* proc = Audio_unit_get_proc(au, i);
        if (proc == NULL ||
                !Device_is_existent((const Device*)proc) ||
                !Processor_get_voice_signals(proc))
            continue;

        const Proc_state* proc_state = (Proc_state*)Device_states_get_state(
                dstates, Device_get_id((const Device*)proc));

        Voice_state_get_size_func* get_vstate_size =
            proc_state->parent.device->dimpl->get_vstate_size;
        if ((get_vstate_size != NULL) && (get_vstate_size() == 0))
            continue;

        char context_str[16] = "";
        snprintf(context_str, 16, "np%hd", (short)i);
        Random* random = Random_init(RANDOM_AUTO, context_str);
        Random_set_seed(random, note_rand_seed);
        const uint64_t voice_rand_seed = Random_get_uint64(random);

        Voice* voice = Voice_group_get_voice(vgroup, voice_index);

        const bool voice_allocated = init_voice(
                ch, voice, au, ch->fg_group_id, proc_state, i, voice_rand_seed);
        if (!voice_allocated)
        {
            // Some of our voices were reallocated
            reset_channel_voices(ch);
            return true;
        }

        ++voice_index;

        Voice_state* vs = voice->state;

        if (vs->proc_type == Proc_type_pitch)
            Pitch_vstate_set_controls(vs, &ch->pitch_controls);

        if (vs->proc_type == Proc_type_force)
        {
            Force_controls* fc = Force_vstate_get_force_controls_mut(vs);
            Force_controls_copy(fc, &ch->force_controls);
        }
    }

    Channel_reset_test_output(ch);

    init_streams(ch, au);

    return true;
}
Пример #13
0
static const char* remap_file(const char* syscall_name, const char* pathname,
                              char* buffer, usage_t usage) {
  char* pos;
  int debug = EKAM_DEBUG;

  /* Ad-hoc debugging can be accomplished by setting debug = 1 when a particular file pattern
   * is matched. */

  if (debug) {
    fprintf(stderr, "remap for %s (%s): %s\n",
            syscall_name, (usage == READ ? "read" : "write"), pathname);
  }

  init_streams();

  if (strlen(pathname) >= PATH_MAX) {
    /* Too long. */
    if (debug) fprintf(stderr, "  name too long\n");
    errno = ENAMETOOLONG;
    return NULL;
  }

  if (get_cached_result(pathname, buffer, usage)) {
    if (debug) fprintf(stderr, "  cached: %s\n", buffer);
    return buffer;
  }

  flockfile(ekam_call_stream);

  if (strncmp(pathname, TAG_PROVIDER_PREFIX, strlen(TAG_PROVIDER_PREFIX)) == 0) {
    /* A tag reference.  Construct the tag name in |buffer|. */
    strcpy(buffer, pathname + strlen(TAG_PROVIDER_PREFIX));

    if (usage == READ) {
      /* Change first slash to a colon to form a tag.  E.g. "header/foo.h" becomes
       * "header:foo.h". */
      pos = strchr(buffer, '/');
      if (pos == NULL) {
        /* This appears to be a tag type without a name, so it should look like a directory.
         * We can use the current directory.  TODO:  Return some fake empty directory instead. */
        funlockfile(ekam_call_stream);
        strcpy(buffer, ".");
        if (debug) fprintf(stderr, "  is directory\n");
        return buffer;
      }
      *pos = ':';
      canonicalizePath(pos + 1);

      if (strcmp(buffer, "canonical:.") == 0) {
        /* HACK:  Don't try to remap top directory. */
        funlockfile(ekam_call_stream);
        if (debug) fprintf(stderr, "  current directory\n");
        return "src";
      }
    }

    /* Ask ekam to remap the file name. */
    fputs(usage == READ ? "findProvider " : "newProvider ", ekam_call_stream);
    fputs(buffer, ekam_call_stream);
    fputs("\n", ekam_call_stream);
  } else if (strcmp(pathname, TMP) == 0 ||
             strcmp(pathname, VAR_TMP) == 0 ||
             strncmp(pathname, TMP_PREFIX, strlen(TMP_PREFIX)) == 0 ||
             strncmp(pathname, VAR_TMP_PREFIX, strlen(VAR_TMP_PREFIX)) == 0) {
    /* Temp file.  Ignore. */
    funlockfile(ekam_call_stream);
    if (debug) fprintf(stderr, "  temp file: %s\n", pathname);
    return pathname;
  } else {
    if (strncmp(pathname, current_dir, strlen(current_dir)) == 0) {
      /* The app is trying to open files in the current directory by absolute path.  Treat it
       * exactly as if it had used a relative path. */
      pathname = pathname + strlen(current_dir);
    } else if (pathname[0] == '/') {
      /* Absolute path.  Note the access but don't remap. */
      if (usage == WRITE) {
        /* Cannot write to absolute paths. */
        funlockfile(ekam_call_stream);
        errno = EACCES;
        if (debug) fprintf(stderr, "  absolute path, can't write\n");
        return NULL;
      }

      fputs("noteInput ", ekam_call_stream);
      fputs(pathname, ekam_call_stream);
      fputs("\n", ekam_call_stream);
      fflush(ekam_call_stream);
      if (ferror_unlocked(ekam_call_stream)) {
        funlockfile(ekam_call_stream);
        fprintf(stderr, "error: Ekam call stream broken.\n");
        abort();
      }
      cache_result(pathname, pathname, usage);
      funlockfile(ekam_call_stream);
      if (debug) fprintf(stderr, "  absolute path: %s\n", pathname);
      return pathname;
    }

    /* Path in current directory. */
    strcpy(buffer, pathname);
    canonicalizePath(buffer);
    if (strcmp(buffer, ".") == 0) {
      /* HACK:  Don't try to remap current directory. */
      funlockfile(ekam_call_stream);
      if (debug) fprintf(stderr, "  current directory\n");
      return "src";
    } else {
      /* Ask ekam to remap the file name. */
      fputs(usage == READ ? "findInput " : "newOutput ", ekam_call_stream);
      fputs(buffer, ekam_call_stream);
      fputs("\n", ekam_call_stream);
    }
  }

  fflush(ekam_call_stream);
  if (ferror_unlocked(ekam_call_stream)) {
    funlockfile(ekam_call_stream);
    fprintf(stderr, "error: Ekam call stream broken.\n");
    abort();
  }

  /* Carefully lock the return stream then unlock the call stream, so that we know that
   * responses will be received in the correct order. */
  flockfile(ekam_return_stream);
  funlockfile(ekam_call_stream);

  /* Read response from Ekam. */
  if (fgets(buffer, PATH_MAX, ekam_return_stream) == NULL) {
    funlockfile(ekam_return_stream);
    fprintf(stderr, "error: Ekam return stream broken.\n");
    abort();
  }

  /* Done reading. */
  funlockfile(ekam_return_stream);

  /* Remove the trailing newline. */
  pos = strchr(buffer, '\n');
  if (pos == NULL) {
    fprintf(stderr, "error: Path returned from Ekam was too long.\n");
    abort();
  }
  *pos = '\0';

  if (*buffer == '\0') {
    /* Not found. */
    errno = ENOENT;
    if (debug) fprintf(stderr, "  ekam says no such file\n");
    return NULL;
  }

  cache_result(pathname, buffer, usage);

  if (debug) fprintf(stderr, "  remapped to: %s\n", buffer);
  return buffer;
}