bvec rat21_fit(bvec par_fit4,double *muI2,bvec xmax) { int nmu=xmax.nel; TMinuit minu(4); minu.SetFCN(ch2_wrap); minu.DefineParameter(0,"A0",par_fit4[0].med(),par_fit4[0].err(),0,0); minu.DefineParameter(1,"A1",par_fit4[1].med(),par_fit4[1].err(),0,0); minu.DefineParameter(2,"A2",par_fit4[2].med(),par_fit4[2].err(),0,0); minu.DefineParameter(3,"A3",0,0.001,0,0); //minu.FixParameter(3); nxfit=nmu; xfit=muI2; yfit=new double[nmu]; erry=new double[nmu]; for(int ifit=0;ifit<nmu;ifit++) erry[ifit]=xmax[ifit].err(); bvec par_fitR(4,nboot,njack); for(int iboot=0;iboot<=nboot;iboot++) { for(int ifit=0;ifit<nmu;ifit++) yfit[ifit]=xmax[ifit][iboot]; minu.Migrad(); double dum; for(int ipar=0;ipar<4;ipar++) minu.GetParameter(ipar,par_fitR[ipar].data[iboot],dum); } return par_fitR; }
static void GenModList_accumGen(GenModList *self, const Generator *gen) { Generator *i = VECTOR_ITER_BEGIN(self->gens); Generator *end = VECTOR_ITER_END(self->gens); for(;i != end;i++) { if(i->mGenerator == gen->mGenerator) { if(gen->mGenerator == 43 || gen->mGenerator == 44) { /* Range generators accumulate by taking the intersection of * the two ranges. */ ALushort low = maxu(i->mAmount&0x00ff, gen->mAmount&0x00ff); ALushort high = minu(i->mAmount&0xff00, gen->mAmount&0xff00); i->mAmount = low | high; } else i->mAmount += gen->mAmount; return; } } if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE) { ERR("Failed to insert generator (from %d elements)\n", VECTOR_SIZE(self->gens)); return; } if(gen->mGenerator < 60) VECTOR_BACK(self->gens).mAmount += DefaultGenValue[gen->mGenerator]; }
// Calculate the elevation indices given the polar elevation in radians. // This will return two indices between 0 and (ELEV_COUNT-1) and an // interpolation factor between 0.0 and 1.0. static void CalcEvIndices(ALfloat ev, ALuint *evidx, ALfloat *evmu) { ev = (F_PI_2 + ev) * (ELEV_COUNT-1) / F_PI; evidx[0] = fastf2u(ev); evidx[1] = minu(evidx[0] + 1, ELEV_COUNT-1); *evmu = ev - evidx[0]; }
/* Calculate the elevation indices given the polar elevation in radians. * This will return two indices between 0 and (Hrtf->evCount - 1) and an * interpolation factor between 0.0 and 1.0. */ static void CalcEvIndices(const struct Hrtf *Hrtf, ALfloat ev, ALuint *evidx, ALfloat *evmu) { ev = (F_PI_2 + ev) * (Hrtf->evCount-1) / F_PI; evidx[0] = fastf2u(ev); evidx[1] = minu(evidx[0] + 1, Hrtf->evCount-1); *evmu = ev - evidx[0]; }
static void skip(Reader *stream, ALuint amt) { while(amt > 0 && !READERR(stream)) { char buf[4096]; amt -= Reader_read(stream, buf, minu(sizeof(buf), amt)); } }
static bool ShipTrackFollower(TileIndex tile, TrackPathFinder *pfs, uint length) { /* Found dest? */ if (tile == pfs->dest_coords) { pfs->best_bird_dist = 0; pfs->best_length = minu(pfs->best_length, length); return true; } /* Skip this tile in the calculation */ if (tile != pfs->skiptile) { pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile)); } return false; }
static void init_phys_mem_map(struct multiboot_info *mbi) { const unsigned long phys_max = (unsigned long)PHYS_MEM_MAX; unsigned long phys_mem_size = 0; unsigned long mmap_entry = mbi->mmap_addr; unsigned long mmap_end = mmap_entry + mbi->mmap_length; debug("Physical memory map:\n"); while (mmap_entry < mmap_end) { const struct multiboot_mmap_entry *entry = (void *)mmap_entry; mmap_entry += entry->size + sizeof(entry->size); if (entry->addr > phys_max) continue; const unsigned long begin = entry->addr; const unsigned long end = minu(begin + entry->len, phys_max); const unsigned type = entry->type; if (type == MULTIBOOT_AVAILABLE) { if (end > phys_mem_size) phys_mem_size = end; boot_mem_add(begin, end); } else { boot_mem_reserve(begin, end); } debug("memory region: 0x%x-0x%x type=%u\n", begin, end - 1, type); } page_frame_count = phys_mem_size >> PAGE_SHIFT; lowmem_page_frame_count = minu(page_frame_count, LOWMEM_PAGE_FRAMES); debug("Page frames at all: 0x%x\n", page_frame_count); debug("Low mem page frames at all: 0x%x\n", lowmem_page_frame_count); }
virtual void OnQueryTextFinished(char *str) { if (str == NULL) return; const Vehicle *v = this->vehicle; uint32 p1 = PackTimetableArgs(v, this->sel_index); uint64 time = StrEmpty(str) ? 0 : strtoul(str, NULL, 10); if (!_settings_client.gui.timetable_in_ticks) time *= DAY_TICKS; uint32 p2 = minu(time, UINT16_MAX); DoCommandP(0, p1, p2, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); }
virtual void OnQueryTextFinished(char *str) { if (str == NULL) return; const Vehicle *v = this->vehicle; uint32 p1 = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); uint64 val = StrEmpty(str) ? 0 : strtoul(str, NULL, 10); if (this->query_is_speed_query) { val = ConvertDisplaySpeedToKmhishSpeed(val); } else { if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS; } uint32 p2 = minu(val, UINT16_MAX); DoCommandP(0, p1, p2, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); }
static struct Hrtf *LoadHrtf(ALuint deviceRate) { const char *fnamelist = NULL; if(!ConfigValueStr(NULL, "hrtf_tables", &fnamelist)) return NULL; while(*fnamelist != '\0') { struct Hrtf *Hrtf = NULL; char fname[PATH_MAX]; ALchar magic[8]; ALuint i; FILE *f; while(isspace(*fnamelist) || *fnamelist == ',') fnamelist++; i = 0; while(*fnamelist != '\0' && *fnamelist != ',') { const char *next = strpbrk(fnamelist, "%,"); while(fnamelist != next && *fnamelist && i < sizeof(fname)) fname[i++] = *(fnamelist++); if(!next || *next == ',') break; /* *next == '%' */ next++; if(*next == 'r') { int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate); i += minu(wrote, sizeof(fname)-i); next++; } else if(*next == '%') { if(i < sizeof(fname)) fname[i++] = '%'; next++; } else ERR("Invalid marker '%%%c'\n", *next); fnamelist = next; } i = minu(i, sizeof(fname)-1); fname[i] = '\0'; while(i > 0 && isspace(fname[i-1])) i--; fname[i] = '\0'; if(fname[0] == '\0') continue; TRACE("Loading %s...\n", fname); f = fopen(fname, "rb"); if(f == NULL) { ERR("Could not open %s\n", fname); continue; } if(fread(magic, 1, sizeof(magic), f) != sizeof(magic)) ERR("Failed to read magic marker\n"); else { if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0) { TRACE("Detected data set format v0\n"); Hrtf = LoadHrtf00(f, deviceRate); } else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0) { TRACE("Detected data set format v1\n"); Hrtf = LoadHrtf01(f, deviceRate); } else ERR("Invalid magic marker: \"%.8s\"\n", magic); } fclose(f); f = NULL; if(Hrtf) { Hrtf->next = LoadedHrtfs; LoadedHrtfs = Hrtf; TRACE("Loaded HRTF support for format: %s %uhz\n", DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate); return Hrtf; } ERR("Failed to load %s\n", fname); } return NULL; }
StringID EndGameGetPerformanceTitleFromValue(uint value) { value = minu(value / 64, lengthof(_endgame_perf_titles) - 1); return _endgame_perf_titles[value]; }
static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE], ALuint NumChannels) { ALuint it, kt; ALuint base; for(base = 0;base < SamplesToDo;) { ALfloat temps[256]; ALuint td = minu(256, SamplesToDo-base); ALfloat gain = state->GainCtrl; for(it = 0;it < td;it++) { ALfloat smp = SamplesIn[it+base]; ALfloat a[3], b[3]; ALfloat alpha, w0; ALfloat amplitude; ALfloat cutoff; /* Similar to compressor, we get the current amplitude of the * incoming signal, and attack or release to reach it. */ amplitude = fabsf(smp); if(amplitude > gain) gain = minf(gain*state->AttackRate, amplitude); else if(amplitude < gain) gain = maxf(gain*state->ReleaseRate, amplitude); gain = maxf(gain, GAIN_SILENCE_THRESHOLD); /* FIXME: What range does the filter cover? */ cutoff = lerp(20.0f, 20000.0f, minf(gain/state->PeakGain, 1.0f)); /* The code below is like calling ALfilterState_setParams with * ALfilterType_LowPass. However, instead of passing a bandwidth, * we use the resonance property for Q. This also inlines the call. */ w0 = F_TAU * cutoff / state->Frequency; /* FIXME: Resonance controls the resonant peak, or Q. How? Not sure * that Q = resonance*0.1. */ alpha = sinf(w0) / (2.0f * state->Resonance*0.1f); b[0] = (1.0f - cosf(w0)) / 2.0f; b[1] = 1.0f - cosf(w0); b[2] = (1.0f - cosf(w0)) / 2.0f; a[0] = 1.0f + alpha; a[1] = -2.0f * cosf(w0); a[2] = 1.0f - alpha; state->LowPass.a1 = a[1] / a[0]; state->LowPass.a2 = a[2] / a[0]; state->LowPass.b1 = b[1] / a[0]; state->LowPass.b2 = b[2] / a[0]; state->LowPass.input_gain = b[0] / a[0]; temps[it] = ALfilterState_processSingle(&state->LowPass, smp); } state->GainCtrl = gain; for(kt = 0;kt < NumChannels;kt++) { ALfloat gain = state->Gain[kt]; if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD)) continue; for(it = 0;it < td;it++) SamplesOut[kt][base+it] += gain * temps[it]; } base += td; } }
static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE]) { ALuint it, kt; ALuint base; for(base = 0;base < SamplesToDo;) { ALfloat temps[64]; ALuint td = minu(SamplesToDo-base, 64); if(state->Enabled) { ALfloat output, smp, amplitude; ALfloat gain = state->GainCtrl; for(it = 0;it < td;it++) { smp = SamplesIn[it+base]; amplitude = fabsf(smp); if(amplitude > gain) gain = minf(gain+state->AttackRate, amplitude); else if(amplitude < gain) gain = maxf(gain-state->ReleaseRate, amplitude); output = 1.0f / clampf(gain, 0.5f, 2.0f); temps[it] = smp * output; } state->GainCtrl = gain; } else { ALfloat output, smp, amplitude; ALfloat gain = state->GainCtrl; for(it = 0;it < td;it++) { smp = SamplesIn[it+base]; amplitude = 1.0f; if(amplitude > gain) gain = minf(gain+state->AttackRate, amplitude); else if(amplitude < gain) gain = maxf(gain-state->ReleaseRate, amplitude); output = 1.0f / clampf(gain, 0.5f, 2.0f); temps[it] = smp * output; } state->GainCtrl = gain; } for(kt = 0;kt < MAX_OUTPUT_CHANNELS;kt++) { ALfloat gain = state->Gain[kt]; if(!(gain > GAIN_SILENCE_THRESHOLD)) continue; for(it = 0;it < td;it++) SamplesOut[kt][base+it] += gain * temps[it]; } base += td; } }
static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name) //{{{ { char *pulse_name = NULL; pulse_data *data; pa_stream_flags_t flags = 0; pa_stream_state_t state; pa_channel_map chanmap; if(!allCaptureDevNameMap) probe_devices(AL_TRUE); if(!device_name) device_name = pulse_device; else if(strcmp(device_name, pulse_device) != 0) { ALuint i; for(i = 0;i < numCaptureDevNames;i++) { if(strcmp(device_name, allCaptureDevNameMap[i].name) == 0) { pulse_name = allCaptureDevNameMap[i].device_name; break; } } if(i == numCaptureDevNames) return ALC_INVALID_VALUE; } if(pulse_open(device, device_name) == ALC_FALSE) return ALC_INVALID_VALUE; data = device->ExtraData; pa_threaded_mainloop_lock(data->loop); data->samples = device->UpdateSize * device->NumUpdates; data->frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->samples = maxu(data->samples, 100 * device->Frequency / 1000); if(!(data->ring = CreateRingBuffer(data->frame_size, data->samples))) { pa_threaded_mainloop_unlock(data->loop); goto fail; } data->attr.minreq = -1; data->attr.prebuf = -1; data->attr.maxlength = data->samples * data->frame_size; data->attr.tlength = -1; data->attr.fragsize = minu(data->samples, 50*device->Frequency/1000) * data->frame_size; data->spec.rate = device->Frequency; data->spec.channels = ChannelsFromDevFmt(device->FmtChans); switch(device->FmtType) { case DevFmtUByte: data->spec.format = PA_SAMPLE_U8; break; case DevFmtShort: data->spec.format = PA_SAMPLE_S16NE; break; case DevFmtFloat: data->spec.format = PA_SAMPLE_FLOAT32NE; break; case DevFmtByte: case DevFmtUShort: ERR("Capture format type %#x capture not supported on PulseAudio\n", device->FmtType); pa_threaded_mainloop_unlock(data->loop); goto fail; } if(pa_sample_spec_valid(&data->spec) == 0) { ERR("Invalid sample format\n"); pa_threaded_mainloop_unlock(data->loop); goto fail; } if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX)) { ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels); pa_threaded_mainloop_unlock(data->loop); goto fail; } data->stream = pa_stream_new(data->context, "Capture Stream", &data->spec, &chanmap); if(!data->stream) { ERR("pa_stream_new() failed: %s\n", pa_strerror(pa_context_errno(data->context))); pa_threaded_mainloop_unlock(data->loop); goto fail; } pa_stream_set_state_callback(data->stream, stream_state_callback, data->loop); flags |= PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY; if(pa_stream_connect_record(data->stream, pulse_name, &data->attr, flags) < 0) { ERR("Stream did not connect: %s\n", pa_strerror(pa_context_errno(data->context))); pa_stream_unref(data->stream); data->stream = NULL; pa_threaded_mainloop_unlock(data->loop); goto fail; } while((state=pa_stream_get_state(data->stream)) != PA_STREAM_READY) { if(!PA_STREAM_IS_GOOD(state)) { ERR("Stream did not get ready: %s\n", pa_strerror(pa_context_errno(data->context))); pa_stream_unref(data->stream); data->stream = NULL; pa_threaded_mainloop_unlock(data->loop); goto fail; } pa_threaded_mainloop_wait(data->loop); } pa_stream_set_state_callback(data->stream, stream_state_callback2, device); pa_threaded_mainloop_unlock(data->loop); return ALC_NO_ERROR; fail: pulse_close(device); return ALC_INVALID_VALUE; } //}}}
static ALCenum alsa_open_capture(ALCdevice *Device, const ALCchar *deviceName) { const char *driver = NULL; snd_pcm_hw_params_t *hp; snd_pcm_uframes_t bufferSizeInFrames; snd_pcm_uframes_t periodSizeInFrames; ALboolean needring = AL_FALSE; snd_pcm_format_t format; const char *funcerr; alsa_data *data; int err; if(deviceName) { size_t idx; if(!allCaptureDevNameMap) allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); for(idx = 0;idx < numCaptureDevNames;idx++) { if(strcmp(deviceName, allCaptureDevNameMap[idx].name) == 0) { driver = allCaptureDevNameMap[idx].device; break; } } if(idx == numCaptureDevNames) return ALC_INVALID_VALUE; } else { deviceName = alsaDevice; driver = GetConfigValue("alsa", "capture", "default"); } data = (alsa_data*)calloc(1, sizeof(alsa_data)); err = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); if(err < 0) { ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(err)); free(data); return ALC_INVALID_VALUE; } format = -1; switch(Device->FmtType) { case DevFmtByte: format = SND_PCM_FORMAT_S8; break; case DevFmtUByte: format = SND_PCM_FORMAT_U8; break; case DevFmtShort: format = SND_PCM_FORMAT_S16; break; case DevFmtUShort: format = SND_PCM_FORMAT_U16; break; case DevFmtInt: format = SND_PCM_FORMAT_S32; break; case DevFmtUInt: format = SND_PCM_FORMAT_U32; break; case DevFmtFloat: format = SND_PCM_FORMAT_FLOAT; break; } funcerr = NULL; bufferSizeInFrames = maxu(Device->UpdateSize*Device->NumUpdates, 100*Device->Frequency/1000); periodSizeInFrames = minu(bufferSizeInFrames, 25*Device->Frequency/1000); snd_pcm_hw_params_malloc(&hp); #define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error CHECK(snd_pcm_hw_params_any(data->pcmHandle, hp)); /* set interleaved access */ CHECK(snd_pcm_hw_params_set_access(data->pcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED)); /* set format (implicitly sets sample bits) */ CHECK(snd_pcm_hw_params_set_format(data->pcmHandle, hp, format)); /* set channels (implicitly sets frame bits) */ CHECK(snd_pcm_hw_params_set_channels(data->pcmHandle, hp, ChannelsFromDevFmt(Device->FmtChans))); /* set rate (implicitly constrains period/buffer parameters) */ CHECK(snd_pcm_hw_params_set_rate(data->pcmHandle, hp, Device->Frequency, 0)); /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ if(snd_pcm_hw_params_set_buffer_size_min(data->pcmHandle, hp, &bufferSizeInFrames) < 0) { TRACE("Buffer too large, using intermediate ring buffer\n"); needring = AL_TRUE; CHECK(snd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, hp, &bufferSizeInFrames)); } /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ CHECK(snd_pcm_hw_params_set_period_size_near(data->pcmHandle, hp, &periodSizeInFrames, NULL)); /* install and prepare hardware configuration */ CHECK(snd_pcm_hw_params(data->pcmHandle, hp)); /* retrieve configuration info */ CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, NULL)); #undef CHECK snd_pcm_hw_params_free(hp); hp = NULL; if(needring) { data->ring = CreateRingBuffer(FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType), Device->UpdateSize*Device->NumUpdates); if(!data->ring) { ERR("ring buffer create failed\n"); goto error2; } data->size = snd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames); data->buffer = malloc(data->size); if(!data->buffer) { ERR("buffer malloc failed\n"); goto error2; } } Device->DeviceName = strdup(deviceName); Device->ExtraData = data; return ALC_NO_ERROR; error: ERR("%s failed: %s\n", funcerr, snd_strerror(err)); if(hp) snd_pcm_hw_params_free(hp); error2: free(data->buffer); DestroyRingBuffer(data->ring); snd_pcm_close(data->pcmHandle); free(data); Device->ExtraData = NULL; return ALC_INVALID_VALUE; }
SWR_FN void swr_render_model(swr_render_target *target, u32 render_mode, model *model, vec3 cam_pos, mat4 model_mat, mat4 viewproj_mat, mat4 screen_mat, vec3 sun_direction, col4 sun_col, float ambient_intencity, mem_pool *pool) { tex2d target_tex = *target->texture; float *z_buffer = target->z_buffer; u8 *old_hi_ptr = pool->hi; vec4 *vertices = (vec4 *)mem_push_back(pool, model->nvertices * sizeof(*vertices)); vec3 *cam_directions = (vec3 *)mem_push_back(pool, model->nvertices * sizeof(*cam_directions)); for (u32 i = 0, e = model->nvertices; i < e; ++i) { vec3 v = mul_m4v4(model_mat, v3_to_v4(model->vertices[i], 1.0f)).xyz; cam_directions[i] = norm_v3(sub_v3(v, cam_pos)); vertices[i] = mul_m4v4(viewproj_mat, v3_to_v4(v, 1.0f)); } face **culled_faces = (face **)mem_push_back(pool, model->nface_groups * sizeof(*culled_faces)); u32 *nculled_faces = (u32 *)mem_push_back(pool, model->nface_groups * sizeof(*nculled_faces)); for (u32 face_group = 0; face_group < model->nface_groups; ++face_group) { face *src_faces = model->face_groups[face_group].faces; u32 nsrc_faces = model->face_groups[face_group].nfaces; face *faces = culled_faces[face_group] = (face *)mem_push_back(pool, nsrc_faces * sizeof(*faces)); u32 nfaces = 0; for (u32 i = 0; i < nsrc_faces; ++i) { face face = src_faces[i]; b32 inside_frustrum = true; for (u32 j = 0; j < 3; ++j) { vec4 vertex = vertices[face.v[j]]; if (vertex.x > vertex.w || vertex.x < -vertex.w || vertex.y > vertex.w || vertex.y < -vertex.w || vertex.z > vertex.w || vertex.z < -vertex.w || vertex.w == 0) { inside_frustrum = false; break; } } if (inside_frustrum) faces[nfaces++] = face; } nculled_faces[face_group] = nfaces; } // TODO: avoid computing irrelevant data (?) for (u32 i = 0; i < model->nvertices; ++i) { vec4 vertex = vertices[i]; vertex = div_v4f(vertex, vertex.w); vertex = mul_m4v4(screen_mat, vertex); vertices[i] = vertex; } for (u32 face_group = 0; face_group < model->nface_groups; ++face_group) { face *faces = culled_faces[face_group]; u32 nfaces = nculled_faces[face_group]; material *material = model->face_groups[face_group].material; for (u32 i = 0; i < nfaces; ++i) { face face = faces[i]; vec4 verts[] = {vertices[face.v[0]], vertices[face.v[1]], vertices[face.v[2]]}; u32 x1 = (u32)verts[0].x; u32 y1 = (u32)verts[0].y; u32 x2 = (u32)verts[1].x; u32 y2 = (u32)verts[1].y; u32 x3 = (u32)verts[2].x; u32 y3 = (u32)verts[2].y; if (render_mode & (SRM_SHADED | SRM_TEXTURED)) { u32 minX = minu(x1, minu(x2, x3)); u32 minY = minu(y1, minu(y2, y3)); u32 maxX = maxu(x1, maxu(x2, x3)) + 1; u32 maxY = maxu(y1, maxu(y2, y3)) + 1; vec3 norms[3]; float lum[3]; if (render_mode & SRM_SHADED) { // TODO: apply reverse transformations to normales norms[0] = model->normales[face.n[0]]; norms[1] = model->normales[face.n[1]]; norms[2] = model->normales[face.n[2]]; float diffuse[3]; for (u32 j = 0; j < 3; ++j) diffuse[j] = clamp(dot_v3(norms[j], sun_direction), 0, 1.0f); vec3 L = neg_v3(sun_direction); float specular[3] = {0}; for (u32 j = 0; j < 3; ++j) { if (diffuse[j]) { vec3 V = cam_directions[face.v[j]]; vec3 H = norm_v3(add_v3(V, L)); specular[j] = (float)pow(dot_v3(H, norms[j]), 32); } } for (u32 j = 0; j < 3; ++j) lum[j] = ambient_intencity + diffuse[j] + specular[j]; } vec2 face_uvs[3]; face_uvs[0] = model->uvs[face.uv[0]]; face_uvs[1] = model->uvs[face.uv[1]]; face_uvs[2] = model->uvs[face.uv[2]]; vec2 a = {(float)x1, (float)y1}; vec2 b = {(float)x2, (float)y2}; vec2 c = {(float)x3, (float)y3}; vec2 v0 = sub_v2(b, a); vec2 v1 = sub_v2(c, a); for (u32 x = minX; x < maxX; ++x) { for (u32 y = minY; y < maxY; ++y) { // calculate barycentric coords... vec2 p = {(float)x, (float)y}; vec2 v2 = sub_v2(p, a); float d00 = dot_v2(v0, v0); float d01 = dot_v2(v0, v1); float d11 = dot_v2(v1, v1); float d20 = dot_v2(v2, v0); float d21 = dot_v2(v2, v1); float denom = d00 * d11 - d01 * d01; float v = (d11 * d20 - d01 * d21) / denom; float w = (d00 * d21 - d01 * d20) / denom; float u = 1.0f - v - w; if (!(v >= -0.001 && w >= -0.001 && u >= -0.001)) continue; u32 z_buff_idx = y * target_tex.width + x; float z = verts[1].z * v + verts[2].z * w + verts[0].z * u; if (z_buffer[z_buff_idx] > z) { float l = 1.0f; if (render_mode & SRM_SHADED) { l = lum[1] * v + lum[2] * w + lum[0] * u; } col4 texel = {255, 255, 255, 255}; if ((render_mode & SRM_TEXTURED) && material->diffuse) { float tu = face_uvs[1].x * v + face_uvs[2].x * w + face_uvs[0].x * u; float tv = face_uvs[1].y * v + face_uvs[2].y * w + face_uvs[0].y * u; tu *= material->diffuse->width; tv *= material->diffuse->height; texel = *sample_t2d(*material->diffuse, (u32)tu, (u32)tv); } col4 fragment_col = { .e[3] = 255 }; for (u32 j = 0; j < 3; ++j) { float cl = sun_col.e[j] * l / 255.0f; fragment_col.e[j] = (u8)clamp(texel.e[j] * cl, 0, 255.0f); } *sample_t2d(target_tex, x, y) = fragment_col; z_buffer[z_buff_idx] = z; } } } } } if (render_mode & SRM_WIREFRAME) { for (u32 i = 0; i < nfaces; ++i) { const col4 model_col = {255, 255, 255, 255}; vec4 v1 = vertices[faces[i].v[0]]; vec4 v2 = vertices[faces[i].v[1]]; vec4 v3 = vertices[faces[i].v[2]]; s32 x1 = (s32)v1.x; s32 y1 = (s32)v1.y; s32 x2 = (s32)v2.x; s32 y2 = (s32)v2.y; s32 x3 = (s32)v3.x; s32 y3 = (s32)v3.y; swr_line(x1, y1, x2, y2, model_col, target_tex); swr_line(x2, y2, x3, y3, model_col, target_tex); swr_line(x3, y3, x1, y1, model_col, target_tex); } } }
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { ALuint SamplesToDo; ALeffectslot **slot, **slot_end; ALvoice *voice, *voice_end; ALCcontext *ctx; FPUCtl oldMode; ALuint i, c; SetMixerFPUMode(&oldMode); while(size > 0) { ALfloat (*OutBuffer)[BUFFERSIZE]; ALuint OutChannels; IncrementRef(&device->MixCount); OutBuffer = device->DryBuffer; OutChannels = device->NumChannels; SamplesToDo = minu(size, BUFFERSIZE); for(c = 0;c < OutChannels;c++) memset(OutBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); if(device->Hrtf) { /* Set OutBuffer/OutChannels to correspond to the actual output * with HRTF. Make sure to clear them too. */ OutBuffer += OutChannels; OutChannels = 2; for(c = 0;c < OutChannels;c++) memset(OutBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); } V0(device->Backend,lock)(); V(device->Synth,process)(SamplesToDo, OutBuffer, OutChannels); ctx = ATOMIC_LOAD(&device->ContextList); while(ctx) { ALenum DeferUpdates = ctx->DeferUpdates; ALenum UpdateSources = AL_FALSE; if(!DeferUpdates) UpdateSources = ATOMIC_EXCHANGE(ALenum, &ctx->UpdateSources, AL_FALSE); if(UpdateSources) CalcListenerParams(ctx->Listener); /* source processing */ voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; while(voice != voice_end) { ALsource *source = voice->Source; if(!source) goto next; if(source->state != AL_PLAYING && source->state != AL_PAUSED) { voice->Source = NULL; goto next; } if(!DeferUpdates && (ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)) voice->Update(voice, source, ctx); if(source->state != AL_PAUSED) MixSource(voice, source, device, SamplesToDo); next: voice++; } /* effect slot processing */ slot = VECTOR_ITER_BEGIN(ctx->ActiveAuxSlots); slot_end = VECTOR_ITER_END(ctx->ActiveAuxSlots); while(slot != slot_end) { if(!DeferUpdates && ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE)) V((*slot)->EffectState,update)(device, *slot); V((*slot)->EffectState,process)(SamplesToDo, (*slot)->WetBuffer[0], device->DryBuffer, device->NumChannels); for(i = 0;i < SamplesToDo;i++) (*slot)->WetBuffer[0][i] = 0.0f; slot++; } ctx = ctx->next; } slot = &device->DefaultSlot; if(*slot != NULL) { if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE)) V((*slot)->EffectState,update)(device, *slot); V((*slot)->EffectState,process)(SamplesToDo, (*slot)->WetBuffer[0], device->DryBuffer, device->NumChannels); for(i = 0;i < SamplesToDo;i++) (*slot)->WetBuffer[0][i] = 0.0f; } /* Increment the clock time. Every second's worth of samples is * converted and added to clock base so that large sample counts don't * overflow during conversion. This also guarantees an exact, stable * conversion. */ device->SamplesDone += SamplesToDo; device->ClockBase += (device->SamplesDone/device->Frequency) * DEVICE_CLOCK_RES; device->SamplesDone %= device->Frequency; V0(device->Backend,unlock)(); if(device->Hrtf) { HrtfMixerFunc HrtfMix = SelectHrtfMixer(); ALuint irsize = GetHrtfIrSize(device->Hrtf); for(c = 0;c < device->NumChannels;c++) HrtfMix(OutBuffer, device->DryBuffer[c], 0, device->Hrtf_Offset, 0, irsize, &device->Hrtf_Params[c], &device->Hrtf_State[c], SamplesToDo ); device->Hrtf_Offset += SamplesToDo; } else if(device->Bs2b) { /* Apply binaural/crossfeed filter */ for(i = 0;i < SamplesToDo;i++) { float samples[2]; samples[0] = device->DryBuffer[0][i]; samples[1] = device->DryBuffer[1][i]; bs2b_cross_feed(device->Bs2b, samples); device->DryBuffer[0][i] = samples[0]; device->DryBuffer[1][i] = samples[1]; } } if(buffer) { #define WRITE(T, a, b, c, d) do { \ Write_##T((a), (b), (c), (d)); \ buffer = (T*)buffer + (c)*(d); \ } while(0) switch(device->FmtType) { case DevFmtByte: WRITE(ALbyte, OutBuffer, buffer, SamplesToDo, OutChannels); break; case DevFmtUByte: WRITE(ALubyte, OutBuffer, buffer, SamplesToDo, OutChannels); break; case DevFmtShort: WRITE(ALshort, OutBuffer, buffer, SamplesToDo, OutChannels); break; case DevFmtUShort: WRITE(ALushort, OutBuffer, buffer, SamplesToDo, OutChannels); break; case DevFmtInt: WRITE(ALint, OutBuffer, buffer, SamplesToDo, OutChannels); break; case DevFmtUInt: WRITE(ALuint, OutBuffer, buffer, SamplesToDo, OutChannels); break; case DevFmtFloat: WRITE(ALfloat, OutBuffer, buffer, SamplesToDo, OutChannels); break; } #undef WRITE } size -= SamplesToDo; IncrementRef(&device->MixCount); } RestoreFPUMode(&oldMode); }
static ALuint PulseProc(ALvoid *param) { ALCdevice *Device = param; pulse_data *data = Device->ExtraData; ALuint buffer_size; ALint update_size; size_t frame_size; ssize_t len; SetRTPriority(); pa_threaded_mainloop_lock(data->loop); frame_size = pa_frame_size(&data->spec); update_size = Device->UpdateSize * frame_size; /* Sanitize buffer metrics, in case we actually have less than what we * asked for. */ buffer_size = minu(update_size*Device->NumUpdates, data->attr.tlength); update_size = minu(update_size, buffer_size/2); do { len = pa_stream_writable_size(data->stream) - data->attr.tlength + buffer_size; if(len < update_size) { if(pa_stream_is_corked(data->stream) == 1) { pa_operation *o; o = pa_stream_cork(data->stream, 0, NULL, NULL); if(o) pa_operation_unref(o); } pa_threaded_mainloop_unlock(data->loop); Sleep(1); pa_threaded_mainloop_lock(data->loop); continue; } len -= len%update_size; while(len > 0) { size_t newlen = len; void *buf; pa_free_cb_t free_func = NULL; #if PA_CHECK_VERSION(0,9,16) if(!pa_stream_begin_write || pa_stream_begin_write(data->stream, &buf, &newlen) < 0) #endif { buf = pa_xmalloc(newlen); free_func = pa_xfree; } pa_threaded_mainloop_unlock(data->loop); aluMixData(Device, buf, newlen/frame_size); pa_threaded_mainloop_lock(data->loop); pa_stream_write(data->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE); len -= newlen; } } while(!data->killNow && Device->Connected); pa_threaded_mainloop_unlock(data->loop); return 0; }
static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name) { const char *pulse_name = NULL; pa_stream_flags_t flags = 0; pa_channel_map chanmap; pulse_data *data; pa_operation *o; ALuint samples; if(device_name) { ALuint i; if(!allCaptureDevNameMap) probe_devices(AL_TRUE); for(i = 0;i < numCaptureDevNames;i++) { if(strcmp(device_name, allCaptureDevNameMap[i].name) == 0) { pulse_name = allCaptureDevNameMap[i].device_name; break; } } if(i == numCaptureDevNames) return ALC_INVALID_VALUE; } if(pulse_open(device) == ALC_FALSE) return ALC_INVALID_VALUE; data = device->ExtraData; pa_threaded_mainloop_lock(data->loop); data->spec.rate = device->Frequency; data->spec.channels = ChannelsFromDevFmt(device->FmtChans); switch(device->FmtType) { case DevFmtUByte: data->spec.format = PA_SAMPLE_U8; break; case DevFmtShort: data->spec.format = PA_SAMPLE_S16NE; break; case DevFmtInt: data->spec.format = PA_SAMPLE_S32NE; break; case DevFmtFloat: data->spec.format = PA_SAMPLE_FLOAT32NE; break; case DevFmtByte: case DevFmtUShort: case DevFmtUInt: ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType)); pa_threaded_mainloop_unlock(data->loop); goto fail; } if(pa_sample_spec_valid(&data->spec) == 0) { ERR("Invalid sample format\n"); pa_threaded_mainloop_unlock(data->loop); goto fail; } if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX)) { ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels); pa_threaded_mainloop_unlock(data->loop); goto fail; } samples = device->UpdateSize * device->NumUpdates; samples = maxu(samples, 100 * device->Frequency / 1000); data->attr.minreq = -1; data->attr.prebuf = -1; data->attr.maxlength = samples * pa_frame_size(&data->spec); data->attr.tlength = -1; data->attr.fragsize = minu(samples, 50*device->Frequency/1000) * pa_frame_size(&data->spec); flags |= PA_STREAM_DONT_MOVE; flags |= PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY; data->stream = connect_record_stream(pulse_name, data->loop, data->context, flags, &data->attr, &data->spec, &chanmap); if(!data->stream) { pa_threaded_mainloop_unlock(data->loop); goto fail; } pa_stream_set_state_callback(data->stream, stream_state_callback2, device); data->device_name = strdup(pa_stream_get_device_name(data->stream)); o = pa_context_get_source_info_by_name(data->context, data->device_name, source_name_callback, device); WAIT_FOR_OPERATION(o, data->loop); pa_threaded_mainloop_unlock(data->loop); return ALC_NO_ERROR; fail: pulse_close(device); return ALC_INVALID_VALUE; }
static int ALCopenslPlayback_mixerProc(void *arg) { ALCopenslPlayback *self = arg; ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; SLAndroidSimpleBufferQueueItf bufferQueue; ll_ringbuffer_data_t data[2]; SLPlayItf player; SLresult result; size_t padding; SetRTPriority(); althrd_setname(althrd_current(), MIXER_THREAD_NAME); result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue); PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDSIMPLEBUFFERQUEUE"); if(SL_RESULT_SUCCESS == result) { result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player); PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY"); } if(SL_RESULT_SUCCESS != result) { ALCopenslPlayback_lock(self); aluHandleDisconnect(device); ALCopenslPlayback_unlock(self); return 1; } /* NOTE: The ringbuffer will be larger than the desired buffer metrics. * Calculate the amount of extra space so we know how much to keep unused. */ padding = ll_ringbuffer_write_space(self->mRing) - device->NumUpdates; ALCopenslPlayback_lock(self); while(ATOMIC_LOAD_SEQ(&self->mKillNow) == AL_FALSE && device->Connected) { size_t todo, len0, len1; if(ll_ringbuffer_write_space(self->mRing) <= padding) { SLuint32 state = 0; result = VCALL(player,GetPlayState)(&state); PRINTERR(result, "player->GetPlayState"); if(SL_RESULT_SUCCESS == result && state != SL_PLAYSTATE_PLAYING) { result = VCALL(player,SetPlayState)(SL_PLAYSTATE_PLAYING); PRINTERR(result, "player->SetPlayState"); } if(SL_RESULT_SUCCESS != result) { aluHandleDisconnect(device); break; } /* NOTE: Unfortunately, there is an unavoidable race condition * here. It's possible for the process() method to run, updating * the read pointer and signaling the condition variable, in * between checking the write size and waiting for the condition * variable here. This will cause alcnd_wait to wait until the * *next* process() invocation signals the condition variable * again. * * However, this should only happen if the mixer is running behind * anyway (as ideally we'll be asleep in alcnd_wait by the time the * process() method is invoked), so this behavior is not completely * unwarranted. It's unfortunate since it'll be wasting time * sleeping that could be used to catch up, but there's no way * around it without blocking in the process() method. */ if(ll_ringbuffer_write_space(self->mRing) <= padding) { alcnd_wait(&self->mCond, &STATIC_CAST(ALCbackend,self)->mMutex); continue; } } ll_ringbuffer_get_write_vector(self->mRing, data); todo = data[0].len+data[1].len - padding; len0 = minu(todo, data[0].len); len1 = minu(todo-len0, data[1].len); aluMixData(device, data[0].buf, len0*device->UpdateSize); for(size_t i = 0;i < len0;i++) { result = VCALL(bufferQueue,Enqueue)(data[0].buf, device->UpdateSize*self->mFrameSize); PRINTERR(result, "bufferQueue->Enqueue"); if(SL_RESULT_SUCCESS == result) ll_ringbuffer_write_advance(self->mRing, 1); data[0].buf += device->UpdateSize*self->mFrameSize; } if(len1 > 0) { aluMixData(device, data[1].buf, len1*device->UpdateSize); for(size_t i = 0;i < len1;i++) { result = VCALL(bufferQueue,Enqueue)(data[1].buf, device->UpdateSize*self->mFrameSize); PRINTERR(result, "bufferQueue->Enqueue"); if(SL_RESULT_SUCCESS == result) ll_ringbuffer_write_advance(self->mRing, 1); data[1].buf += device->UpdateSize*self->mFrameSize; } } } ALCopenslPlayback_unlock(self); return 0; }
int main() { read_pars("input"); read_ensemble_pars(base_path,T,ibeta,nmass,mass,iml_un,nlights,data_list_file); TH=L=T/2; int ncombo=nmass*nmass; //load all the corrs double *buf=new double[4*ncombo*T*(njack+1)]; FILE *fin=open_file(combine("%s/%s",base_path,corr_name).c_str(),"r"); int stat=fread(buf,sizeof(double),4*ncombo*(njack+1)*T,fin); if(stat!=4*ncombo*(njack+1)*T) { cerr<<"Error loading data!"<<endl; exit(1); } jvec M(ncombo,njack); jvec Z2(ncombo,njack); //define minuit staff TMinuit minu(2); minu.SetPrintLevel(-1); minu.SetFCN(chi2); corr_fit=new double[TH+1]; corr_err=new double[TH+1]; int ic=0; //fit each combo for(int ims=0;ims<nmass;ims++) for(int imc=0;imc<nmass;imc++) { int ic1=0+2*(imc+nmass*(0+2*ims)); int ic2=1+2*(imc+nmass*(1+2*ims)); printf("%d %d\n",ic1,ic2); //take into account corr jvec corr(T,njack); jvec corr1(T,njack); jvec corr2(T,njack); corr1.put(buf+ic1*T*(njack+1)); corr2.put(buf+ic2*T*(njack+1)); corr=(corr1+corr2)/2; //choose the index of the fitting interval if(ims>=nlights) ifit_int=2; else if(imc>=nlights) ifit_int=1; else ifit_int=0; //simmetrize corr=corr.simmetrized(parity); int ttmin=tmin[ifit_int]; int ttmax=tmax[ifit_int]; jvec Mcor=effective_mass(corr),Z2cor(TH+1,njack); jack Meff=constant_fit(Mcor,ttmin,ttmax); for(int t=0;t<=TH;t++) for(int ijack=0;ijack<=njack;ijack++) Z2cor[t].data[ijack]=corr[t].data[ijack]/fun_fit(1,Meff[ijack],t); jack Z2eff=constant_fit(Z2cor,ttmin,ttmax); if(!isnan(Z2eff[0])) minu.DefineParameter(0,"Z2",Z2eff[0],Z2eff.err(),0,2*Z2eff[0]); if(!isnan(Meff[0])) minu.DefineParameter(1,"M",Meff[0],Meff.err(),0,2*Meff[0]); for(int t=tmin[ifit_int];t<=tmax[ifit_int];t++) corr_err[t]=corr.data[t].err(); //jacknife analysis for(int ijack=0;ijack<njack+1;ijack++) { //copy data so that glob function may access it for(int t=tmin[ifit_int];t<=tmax[ifit_int];t++) corr_fit[t]=corr.data[t].data[ijack]; //fit double dum; minu.Migrad(); minu.GetParameter(0,Z2.data[ic].data[ijack],dum); minu.GetParameter(1,M.data[ic].data[ijack],dum); } //if((ims==iml_un||ims==nlights-1||ims==nlights||ims==nmass-1)&& //(imc==iml_un||imc==nlights-1||imc==nlights||imc==nmass-1)) { //plot eff mass { ofstream out(combine("eff_mass_plot_%02d_%02d.xmg",ims,imc).c_str()); out<<"@type xydy"<<endl; out<<"@s0 line type 0"<<endl; out<<Mcor<<endl; out<<"&"<<endl; out<<"@type xy"<<endl; double av_mass=M[ic].med(); double er_mass=M[ic].err(); out<<tmin[ifit_int]<<" "<<av_mass-er_mass<<endl; out<<tmax[ifit_int]<<" "<<av_mass-er_mass<<endl; out<<tmax[ifit_int]<<" "<<av_mass+er_mass<<endl; out<<tmin[ifit_int]<<" "<<av_mass+er_mass<<endl; out<<tmin[ifit_int]<<" "<<av_mass-er_mass<<endl; } //plot fun { ofstream out(combine("fun_plot_%02d_%02d.xmg",ims,imc).c_str()); out<<"@type xydy"<<endl; out<<"@s0 line type 0"<<endl; out<<corr<<endl; out<<"&"<<endl; out<<"@type xy"<<endl; for(int t=tmin[ifit_int];t<tmax[ifit_int];t++) out<<t<<" "<<fun_fit(Z2[ic][njack],M[ic][njack],t)<<endl; } } cout<<mass[ims]<<" "<<mass[imc]<<" "<<M[ic]<<" "<<Z2[ic]<<" "<<sqrt(Z2[ic])/(sinh(M[ic])*M[ic])*(mass[ims]+mass[imc])<<endl; ic++; } ofstream out("fitted_mass.xmg"); out<<"@type xydy"<<endl; for(int ims=0;ims<nmass;ims++) { //out<<"s0 line type 0"<<endl; for(int imc=0;imc<nmass;imc++) { int ic=imc+nmass*ims; out<<mass[imc]<<" "<<M[ic]<<endl; } out<<"&"<<endl; } M.write_to_binfile(out_file); Z2.append_to_binfile(out_file); return 0; }
static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName) { const char *driver = "default"; snd_pcm_hw_params_t *p; snd_pcm_uframes_t bufferSizeInFrames; snd_pcm_uframes_t periodSizeInFrames; snd_pcm_format_t format; ALuint frameSize; alsa_data *data; char str[128]; char *err; int i; ConfigValueStr("alsa", "capture", &driver); if(!allCaptureDevNameMap) allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); if(!deviceName) deviceName = allCaptureDevNameMap[0].name; else { size_t idx; for(idx = 0;idx < numCaptureDevNames;idx++) { if(allCaptureDevNameMap[idx].name && strcmp(deviceName, allCaptureDevNameMap[idx].name) == 0) { if(idx > 0) { snprintf(str, sizeof(str), "%sCARD=%s,DEV=%d", capture_prefix, allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev); driver = str; } break; } } if(idx == numCaptureDevNames) return ALC_INVALID_VALUE; } data = (alsa_data*)calloc(1, sizeof(alsa_data)); i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); if(i < 0) { ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(i)); free(data); return ALC_INVALID_VALUE; } format = -1; switch(pDevice->FmtType) { case DevFmtByte: format = SND_PCM_FORMAT_S8; break; case DevFmtUByte: format = SND_PCM_FORMAT_U8; break; case DevFmtShort: format = SND_PCM_FORMAT_S16; break; case DevFmtUShort: format = SND_PCM_FORMAT_U16; break; case DevFmtFloat: format = SND_PCM_FORMAT_FLOAT; break; } err = NULL; bufferSizeInFrames = maxu(pDevice->UpdateSize*pDevice->NumUpdates, 100*pDevice->Frequency/1000); periodSizeInFrames = minu(bufferSizeInFrames, 50*pDevice->Frequency/1000); snd_pcm_hw_params_malloc(&p); if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0) err = "any"; /* set interleaved access */ if(i >= 0 && (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) err = "set access"; /* set format (implicitly sets sample bits) */ if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0) err = "set format"; /* set channels (implicitly sets frame bits) */ if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(pDevice->FmtChans))) < 0) err = "set channels"; /* set rate (implicitly constrains period/buffer parameters) */ if(i >= 0 && (i=snd_pcm_hw_params_set_rate(data->pcmHandle, p, pDevice->Frequency, 0)) < 0) err = "set rate near"; /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, p, &bufferSizeInFrames)) < 0) err = "set buffer size near"; /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ if(i >= 0 && (i=snd_pcm_hw_params_set_period_size_near(data->pcmHandle, p, &periodSizeInFrames, NULL)) < 0) err = "set period size near"; /* install and prepare hardware configuration */ if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0) err = "set params"; if(i < 0) { ERR("%s failed: %s\n", err, snd_strerror(i)); snd_pcm_hw_params_free(p); goto error; } if((i=snd_pcm_hw_params_get_period_size(p, &bufferSizeInFrames, NULL)) < 0) { ERR("get size failed: %s\n", snd_strerror(i)); snd_pcm_hw_params_free(p); goto error; } snd_pcm_hw_params_free(p); frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); data->ring = CreateRingBuffer(frameSize, pDevice->UpdateSize*pDevice->NumUpdates); if(!data->ring) { ERR("ring buffer create failed\n"); goto error; } data->size = snd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames); data->buffer = malloc(data->size); if(!data->buffer) { ERR("buffer malloc failed\n"); goto error; } pDevice->szDeviceName = strdup(deviceName); pDevice->ExtraData = data; return ALC_NO_ERROR; error: free(data->buffer); DestroyRingBuffer(data->ring); snd_pcm_close(data->pcmHandle); free(data); pDevice->ExtraData = NULL; return ALC_INVALID_VALUE; }