Пример #1
0
AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
{
    ALCdevice *device;
    ALCcontext *context;
    ALbuffer *ALBuf;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    if(!(n >= 0))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    device = context->Device;
    for(i = 0;i < n;i++)
    {
        if(!buffers[i])
            continue;

        /* Check for valid Buffer ID */
        if((ALBuf=LookupBuffer(device, buffers[i])) == NULL)
            SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
        if(ReadRef(&ALBuf->ref) != 0)
            SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }

    for(i = 0;i < n;i++)
    {
        if((ALBuf=LookupBuffer(device, buffers[i])) != NULL)
            DeleteBuffer(device, ALBuf);
    }

done:
    ALCcontext_DecRef(context);
}
Пример #2
0
AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsfpreset *preset;

    switch(param)
    {
        case AL_MIDI_PRESET_SOFT:
        case AL_MIDI_BANK_SOFT:
            alPresetiSOFT(id, param, values[0]);
            return;
    }

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    if((preset=LookupPreset(device, id)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
    if(ReadRef(&preset->ref) != 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    switch(param)
    {
        default:
            SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}
Пример #3
0
FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg)
{
    ALCwinmmPlayback *self = arg;
    ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
    WAVEHDR *WaveHdr;
    MSG msg;

    SetRTPriority();
    althrd_setname(althrd_current(), MIXER_THREAD_NAME);

    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(msg.message != WOM_DONE)
            continue;

        if(ATOMIC_LOAD(&self->killNow, almemory_order_acquire))
        {
            if(ReadRef(&self->WaveBuffersCommitted) == 0)
                break;
            continue;
        }

        WaveHdr = ((WAVEHDR*)msg.lParam);
        ALCwinmmPlayback_lock(self);
        aluMixData(device, WaveHdr->lpData, WaveHdr->dwBufferLength /
                                            self->Format.nBlockAlign);
        ALCwinmmPlayback_unlock(self);

        // Send buffer back to play more data
        waveOutWrite(self->OutHdl, WaveHdr, sizeof(WAVEHDR));
        IncrementRef(&self->WaveBuffersCommitted);
    }

    return 0;
}
Пример #4
0
int alcnd_signal(alcnd_t *cond)
{
    _int_alcnd_t *icond = cond->Ptr;
    if(ReadRef(&icond->wait_count) > 0)
        SetEvent(icond->events[SIGNAL]);
    return althrd_success;
}
Пример #5
0
AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsfpreset *preset;

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    if((preset=LookupPreset(device, id)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
    if(ReadRef(&preset->ref) != 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    switch(param)
    {
        case AL_MIDI_PRESET_SOFT:
            if(!(value >= 0 && value <= 127))
                SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
            preset->Preset = value;
            break;

        case AL_MIDI_BANK_SOFT:
            if(!(value >= 0 && value <= 128))
                SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
            preset->Bank = value;
            break;

        default:
            SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}
Пример #6
0
int alcnd_broadcast(alcnd_t *cond)
{
    _int_alcnd_t *icond = cond->Ptr;
    if(ReadRef(&icond->wait_count) > 0)
        SetEvent(icond->events[BROADCAST]);
    return althrd_success;
}
Пример #7
0
AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsfpreset *preset;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    if(!(n >= 0))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    device = context->Device;
    for(i = 0;i < n;i++)
    {
        /* Check for valid ID */
        if((preset=LookupPreset(device, ids[i])) == NULL)
            SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
        if(ReadRef(&preset->ref) != 0)
            SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }

    for(i = 0;i < n;i++)
    {
        if((preset=LookupPreset(device, ids[i])) != NULL)
            DeletePreset(device, preset);
    }

done:
    ALCcontext_DecRef(context);
}
Пример #8
0
FORCE_ALIGN static int PlaybackThreadProc(void *arg)
{
    ALCdevice *Device = (ALCdevice*)arg;
    WinMMData *data = Device->ExtraData;
    WAVEHDR *WaveHdr;
    MSG msg;

    SetRTPriority();
    althrd_setname(althrd_current(), MIXER_THREAD_NAME);

    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(msg.message != WOM_DONE)
            continue;

        if(data->killNow)
        {
            if(ReadRef(&data->WaveBuffersCommitted) == 0)
                break;
            continue;
        }

        WaveHdr = ((WAVEHDR*)msg.lParam);
        aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength /
                   data->Format.nBlockAlign);

        // Send buffer back to play more data
        waveOutWrite(data->WaveHandle.Out, WaveHdr, sizeof(WAVEHDR));
        IncrementRef(&data->WaveBuffersCommitted);
    }

    return 0;
}
Пример #9
0
AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values)
{
    ALCdevice *device;
    ALCcontext *context;
    ALbuffer *albuf;

    if(values)
    {
        switch(param)
        {
            case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
            case AL_PACK_BLOCK_ALIGNMENT_SOFT:
                alBufferi(buffer, param, values[0]);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    LockBuffersRead(device);
    if((albuf=LookupBuffer(device, buffer)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);

    if(!(values))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    switch(param)
    {
    case AL_LOOP_POINTS_SOFT:
        WriteLock(&albuf->lock);
        if(ReadRef(&albuf->ref) != 0)
        {
            WriteUnlock(&albuf->lock);
            SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
        }
        if(values[0] >= values[1] || values[0] < 0 ||
           values[1] > albuf->SampleLen)
        {
            WriteUnlock(&albuf->lock);
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        }

        albuf->LoopStart = values[0];
        albuf->LoopEnd = values[1];
        WriteUnlock(&albuf->lock);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    UnlockBuffersRead(device);
    ALCcontext_DecRef(context);
}
Пример #10
0
AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsoundfont *sfont;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    if(!(n >= 0))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    device = context->Device;
    for(i = 0;i < n;i++)
    {
        /* Check for valid soundfont ID */
        if(ids[i] == 0)
        {
            if(!(sfont=device->DefaultSfont))
                continue;
        }
        else if((sfont=LookupSfont(device, ids[i])) == NULL)
            SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
        if(ReadRef(&sfont->ref) != 0)
            SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }

    for(i = 0;i < n;i++)
    {
        if(ids[i] == 0)
        {
            MidiSynth *synth = device->Synth;
            WriteLock(&synth->Lock);
            if(device->DefaultSfont != NULL)
                ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
            device->DefaultSfont = NULL;
            WriteUnlock(&synth->Lock);
            continue;
        }
        else if((sfont=RemoveSfont(device, ids[i])) == NULL)
            continue;

        ALsoundfont_Destruct(sfont);

        memset(sfont, 0, sizeof(*sfont));
        free(sfont);
    }

done:
    ALCcontext_DecRef(context);
}
Пример #11
0
AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsfpreset *preset;
    ALfontsound **sounds;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    if(!(preset=LookupPreset(device, id)))
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
    if(count < 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    if(ReadRef(&preset->ref) != 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);

    if(count == 0)
        sounds = NULL;
    else
    {
        sounds = calloc(count, sizeof(sounds[0]));
        if(!sounds)
            SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);

        for(i = 0;i < count;i++)
        {
            if(!(sounds[i]=LookupFontsound(device, fsids[i])))
            {
                free(sounds);
                SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
            }
        }
    }

    for(i = 0;i < count;i++)
        IncrementRef(&sounds[i]->ref);

    sounds = ExchangePtr((XchgPtr*)&preset->Sounds, sounds);
    count = ExchangeInt(&preset->NumSounds, count);

    for(i = 0;i < count;i++)
        DecrementRef(&sounds[i]->ref);
    free(sounds);

done:
    ALCcontext_DecRef(context);
}
Пример #12
0
static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot)
{
    ALCdevice *device = context->Device;
    const ALeffectslot *root, *next;

    root = slot;
    next = ATOMIC_LOAD(&slot->next);
    if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next))
    {
        const ALeffectslot *cur;
        do {
            cur = root;
            root = slot;
        } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next));
    }
    /* Wait for any mix that may be using these effect slots to finish. */
    while((ReadRef(&device->MixCount)&1) != 0)
        althrd_yield();
}
Пример #13
0
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots)
{
    ALCcontext *context;
    ALeffectslot *slot;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    LockEffectSlotList(context);
    if(n < 0)
        SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effect slots", n);
    if(n == 0) goto done;

    for(i = 0;i < n;i++)
    {
        if((slot=LookupEffectSlot(context, effectslots[i])) == NULL)
            SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u",
                        effectslots[i]);
        if(ReadRef(&slot->ref) != 0)
            SETERR_GOTO(context, AL_INVALID_NAME, done, "Deleting in-use effect slot %u",
                        effectslots[i]);
    }

    // All effectslots are valid
    RemoveActiveEffectSlots(effectslots, n, context);
    for(i = 0;i < n;i++)
    {
        if((slot=LookupEffectSlot(context, effectslots[i])) == NULL)
            continue;
        VECTOR_ELEM(context->EffectSlotList, effectslots[i]-1) = NULL;

        DeinitEffectSlot(slot);

        memset(slot, 0, sizeof(*slot));
        al_free(slot);
    }

done:
    UnlockEffectSlotList(context);
    ALCcontext_DecRef(context);
}
Пример #14
0
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots)
{
    ALCcontext *context;
    ALeffectslot *slot;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    LockEffectSlotsWrite(context);
    if(!(n >= 0))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    for(i = 0;i < n;i++)
    {
        if((slot=LookupEffectSlot(context, effectslots[i])) == NULL)
            SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
        if(ReadRef(&slot->ref) != 0)
            SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }

    // All effectslots are valid
    for(i = 0;i < n;i++)
    {
        if((slot=RemoveEffectSlot(context, effectslots[i])) == NULL)
            continue;
        FreeThunkEntry(slot->id);

        RemoveEffectSlotList(context, slot);
        DeinitEffectSlot(slot);

        memset(slot, 0, sizeof(*slot));
        al_free(slot);
    }

done:
    UnlockEffectSlotsWrite(context);
    ALCcontext_DecRef(context);
}
Пример #15
0
AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsoundfont *sfont;
    Reader reader;

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    if(id == 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    if(!(sfont=LookupSfont(device, id)))
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);

    WriteLock(&sfont->Lock);
    if(ReadRef(&sfont->ref) != 0)
    {
        WriteUnlock(&sfont->Lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }
    if(sfont->NumPresets > 0)
    {
        WriteUnlock(&sfont->Lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }

    reader.cb = cb;
    reader.ptr = user;
    reader.error = 0;
    loadSf2(&reader, sfont, context);
    WriteUnlock(&sfont->Lock);

done:
    ALCcontext_DecRef(context);
}
Пример #16
0
AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids)
{
    ALCdevice *device;
    ALCcontext *context;
    ALsoundfont *sfont;
    ALsfpreset **presets;
    ALsizei i;

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    if(id == 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    if(!(sfont=LookupSfont(device, id)))
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
    if(count < 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    WriteLock(&sfont->Lock);
    if(ReadRef(&sfont->ref) != 0)
    {
        WriteUnlock(&sfont->Lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
    }

    if(count == 0)
        presets = NULL;
    else
    {
        presets = calloc(count, sizeof(presets[0]));
        if(!presets)
        {
            WriteUnlock(&sfont->Lock);
            SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
        }

        for(i = 0;i < count;i++)
        {
            if(!(presets[i]=LookupPreset(device, pids[i])))
            {
                free(presets);
                WriteUnlock(&sfont->Lock);
                SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
            }
        }
    }

    for(i = 0;i < count;i++)
        IncrementRef(&presets[i]->ref);

    presets = ExchangePtr((XchgPtr*)&sfont->Presets, presets);
    count = ExchangeInt(&sfont->NumPresets, count);
    WriteUnlock(&sfont->Lock);

    for(i = 0;i < count;i++)
        DecrementRef(&presets[i]->ref);
    free(presets);

done:
    ALCcontext_DecRef(context);
}
Пример #17
0
void* CDFAlign::ThreadFunc_cuAlign(void* p)
{
	CDFAlign *pThis=(CDFAlign *)p;
	APARA &para=pThis->m_para;
	pThis->m_bRun=true;

	char str[512];
	int i,j;
	bool bSuccess=false;

	//open stack file
	MRC stack;
	if(stack.open(pThis->m_fnStack,"rb")<=0)
	{
		sprintf(str,"Error: Failed to open stack %s .",pThis->m_fnStack);
		Message(str);
		pThis->m_bRun=false;
		return (void *)0;
	}

	//get image size
	int nx=stack.getNx();
	int ny=stack.getNy();
	int nz=stack.getNz();
	sprintf(str,"\nInput Stack: Nx(%d) Ny(%d) Nz(%d)\n\n",nx,ny,nz);
	pThis->TextOutput(str);

	
	int bin=para.bin;
	if(bin<=0) return (void *)0;

	int offsetx=para.crop_offsetx;
	int offsety=para.crop_offsety;
	DIM nsamUnbin=verifyCropSize(nx,ny, offsetx, offsety, para.crop_nsam,bin);
	if(nsamUnbin.x<=0 || nsamUnbin.y<=0 )
	{
		Message("Error: Wrong image Size.");
		pThis->m_bRun=false;
		return (void *)0;
	}

	DIM nsam=nsamUnbin/bin;
	
	int nsamb=nsam.width()+2;
	if(bin==1) sprintf(str,"Crop Image: Offset(%d %d) Dim(%d %d)\n\n",
							offsetx,offsety,nsamUnbin.x,nsamUnbin.y);
	else sprintf(str,"Crop Image: Offset(%d %d) RawDim(%d %d) BinnedDim(%d %d)\n\n",
							offsetx,offsety,nsamUnbin.x,nsamUnbin.y,nsam.x,nsam.y);
	pThis->TextOutput(str);
	pThis->m_nsam=nsam;
	//pThis->m_nsamRaw=nx/bin;

	//allocate memeory	
	size_t size=nsam.width()*nsam.height();
	size_t sizeb=nsamb*nsam.height();
	int sizebUnbin=(nsamUnbin.width()+2)*nsamUnbin.height();
	if(para.nStart<0) para.nStart=0;
	if(para.nEnd>=nz) para.nEnd=nz-1;
	int nframe=para.nEnd-para.nStart+1;
	pThis->UpdateDisplay();

	//host memory
	float *bufmrc=new float[nx*ny];
	float *bufmrcfft=new float[sizebUnbin];
	float *htmp=new float[sizeb];
	float *hbuf=new float[sizeb*nframe];  //host memory for entir stack
	float *hdisp=new float[sizeb];
	float *hsumRaw=new float[sizeb];
	float *hsumCorr=new float[sizeb];
	float *hFSCRaw0=new float[sizeb];  //even number
	float *hFSCRaw1=new float[sizeb];  //odd
	float *hFSCCorr0=new float[sizeb];  //even number
	float *hFSCCorr1=new float[sizeb];   //odd
	size_t refsize=0;
	if(para.bDark) 
	{
		if(pThis->m_pDark!=0) delete [] pThis->m_pDark;
		pThis->m_pDark=ReadRef(pThis->m_fnDark,nx,ny);
		if(pThis->m_pDark==0) 
		{
			Message("Failed to get dark reference.");	
			pThis->m_bRun=false;
			return (void *)0;
		}
		refsize+=nx*ny;
	}
	if(para.bGain) 
	{
		if(pThis->m_pGain!=0) delete [] pThis->m_pGain;
		pThis->m_pGain=ReadRef(pThis->m_fnGain,nx,ny);
		if(pThis->m_pGain==0) 
		{
			Message("Failed to get gain reference.");	
			pThis->m_bRun=false;
			return (void *)0;
		}
		refsize+=nx*ny;
	}
	
	
	sprintf(str,"Allocate host memory: %f Gb\n",(nx*ny+sizeb*(nframe+8)+sizebUnbin+refsize)/256.0/1024.0/1024.0);
	pThis->TextOutput(str);
	if(hbuf==0)
	{
		if(bufmrc!=NULL) delete [] bufmrc;
		Message("Failed to allocate host memeory.");
		pThis->m_bRun=false;
		return (void *)0;
	}


	//device memory
	bool success=initGPU(para.GPUNum);
	if(!success)
	{
		sprintf(str,"Failed to initialize GPU #%d.",para.GPUNum);
		Message(str);
		delete [] bufmrc;
		delete [] hbuf;
		pThis->m_bRun=false;
		return (void *)0;
	}
	

	float *dsum=0;
	float *dsumcorr=0;
	float *dfft=0;
	float *dtmp=0;
	GPUMemAlloc((void **)&dsum,sizeof(float)*sizeb);	
	GPUMemAlloc((void **)&dsumcorr,sizeof(float)*sizeb);	
	GPUMemAlloc((void **)&dtmp,sizeof(float)*sizeb);
	cufftHandle fft_plan,ifft_plan;
	
	//prepare fft for unbinned image
	fft_plan=GPUFFTPlan(nsamUnbin);
	GPUSync();
	GPUMemAlloc((void **)&dfft,sizeof(float)*sizebUnbin);


	//make a list 
	int sizec=(nsam.width()/2+1)*nsam.height();
	MASK *hPosList=new MASK[sizec];
	MASK *dPosList=0;
	MkPosList(hPosList,nsam,para.bfactor);
	GPUMemAlloc((void **)&dPosList,sizeof(MASK)*sizec);
	GPUMemH2D((void **)dPosList,(void **)hPosList,sizeof(MASK)*sizec);

	size_t theFree, theTotal;
	GPUMemCheck(theFree,theTotal);
	sprintf(str,"GPU memory:  free:%.0fMb    total:%.0fMb\n", theFree/1024.0/1024.0, theTotal/1024.0/1024.0);
	pThis->TextOutput(str);

	//Read stack
	pThis->TextOutput("\nRead stack:\n");
	
	float sx=0;
	float sy=0;
	float shiftx,shifty,cc;
	float avgcc=0.0;
	bool bFSCEven=true;
	
	//prepare frame sum numbers
	//Only the frame inside sum range is used for stack and sum output 
	int nStartSum=para.nStartSum-para.nStart;
	int nEndSum=para.nEndSum-para.nStart;	
	if(nStartSum<0) nStartSum=0;
	if(para.nEndSum>para.nEnd) nEndSum=para.nEnd-para.nStart+1;
	if(nEndSum<=nStartSum || nEndSum>=nframe) nEndSum=nframe-1;

	//1. calculate sum
	GPUMemZero((void **)&dsum,sizeof(float)*sizeb);
	GPUSync();
	GPUMemZero((void **)&dsumcorr,sizeof(float)*sizeb);
	GPUSync();
	for(j=para.nStart;j<=para.nEnd;j++)
	{
		//read from file and crop
		if(stack.read2DIm_32bit(bufmrc,j)!=stack.getImSize())
		{
			sprintf(str,"Error when reading #%03d\n",j);
			pThis->TextOutput(str);
		}

		if(para.flp) {	//flip image along y axis
			FlipYAxis(bufmrc, nx, ny);
		}

		//apply gain and dark reference
		if(!ApplyRef(bufmrc, para.bDark, pThis->m_pDark, para.bGain, pThis->m_pGain, nx*ny))
		{
			sprintf(str,"Error when applying dark and/or gain to #%03d\n",j);
			pThis->TextOutput(str);
		}
		
		
		crop2fft(bufmrc,DIM(nx,ny),bufmrcfft,offsetx,offsety,nsamUnbin,bin);
		
		//copy to GPU
		GPUMemH2D((void *)dfft,(void *)bufmrcfft,sizeof(float)*sizebUnbin);
		//do fft
		GPUFFT2d(dfft,fft_plan);
		GPUSync();

		//do binning
		if(bin>1)
		{
			GPUMemBinD2D(dtmp, dfft, nsam, nsamUnbin);
			GPUMemD2D(dfft, dtmp, sizeof(float)*sizeb);
		}

		//Sum
		if( (j-para.nStart)>=nStartSum && (j-para.nStart)<=nEndSum )
		{
			if(bFSCEven) GPUAdd(dsum,dfft,sizeb);
			else GPUAdd(dsumcorr,dfft,sizeb);
			bFSCEven=!bFSCEven;
		}
		//copy ffted image to host
		GPUMemD2H((void *)(hbuf+(j-para.nStart)*sizeb),(void *)dfft,sizeof(float)*sizeb);
		GPUSync();
		
		sprintf(str,"......Read and sum frame #%03d   mean:%f\n",j,(hbuf+(j-para.nStart)*sizeb)[0]/nsam.x/nsam.y);
		pThis->TextOutput(str);
		
	}
	GPUMemD2H((void *)hFSCRaw0,(void *)dsum,sizeof(float)*sizeb);
	GPUMemD2H((void *)hFSCRaw1,(void *)dsumcorr,sizeof(float)*sizeb);
	GPUAdd(dsum,dsumcorr,sizeb);
	GPUSync();
	

	//free memory for unbined image
	delete [] bufmrcfft;
	bufmrcfft=0;
	GPUMemFree((void **)&dfft);
	GPUFFTDestroy(fft_plan);
	fft_plan=0;	
	//finish GPU memory allocate
	GPUMemAlloc((void **)&dfft,sizeof(float)*sizeb);
	GPUMemZero((void **)&dsumcorr,sizeof(float)*sizeb);
	GPUSync();
	ifft_plan=GPUIFFTPlan(nsam);
	GPUSync();
	//copy sum image to host for save and display
	if(para.bDispFFTRaw || para.bSaveRawSum)
	{
		GPUIFFT2d(dsum,ifft_plan);
		GPUSync();
		GPUMultiplyNum(dsum,1.0/size,sizeb);
		GPUMemD2H((void *)hsumRaw,(void *)dsum,sizeof(float)*sizeb);
		fft2buf(bufmrc,hsumRaw,nsam);
	}

	//save
	MRC mrcraw;
	if(para.bSaveRawSum)
	{
		//write to file
		mrcraw.open(pThis->m_fnRawsum,"wb");
		mrcraw.createMRC(bufmrc,nsam.width(),nsam.height(),1);
		//stats
		sprintf(str,"Mean=%f   Min=%f   Max=%f\n",
					mrcraw.m_header.dmean,mrcraw.m_header.dmin,mrcraw.m_header.dmax);
		pThis->TextOutput(str);
		mrcraw.close();
		sprintf(str,"Save Uncorrected Sum to: %s\n",pThis->m_fnRawsum);
		pThis->TextOutput(str);
	}
	
	
	//save un-corrected stack
	MRC stackRaw;
	if(para.bSaveStackRaw)
	{
		pThis->TextOutput("\nWrite uncorrected stack:\n");
		stackRaw.open(pThis->m_fnStackRaw,"wb");
		stackRaw.m_header.nx=nsam.x;
		stackRaw.m_header.ny=nsam.y;
		stackRaw.m_header.nz=nEndSum-nStartSum+1;
		stackRaw.updateHeader();

		for(j=nStartSum;j<=nEndSum;j++)
		{
			//copy to GPU
			GPUMemH2D((void *)dfft,(void *)(hbuf+j*sizeb),sizeof(float)*sizeb);
			//ifft
			GPUIFFT2d(dfft,ifft_plan);
			GPUSync();
			GPUMultiplyNum(dfft,1.0/size,sizeb);
			GPUSync();
			GPUMemD2H((void *)htmp,(void *)dfft,sizeof(float)*sizeb);
			fft2buf(bufmrc,htmp,nsam);
			stackRaw.write2DIm(bufmrc,j-nStartSum);
			
			sprintf(str,"......Write frame #%03d\n",j+para.nStart);
			pThis->TextOutput(str);
		}
		MinMaxMean(bufmrc,nsam.x*nsam.y, stackRaw.m_header.dmin, stackRaw.m_header.dmax, stackRaw.m_header.dmean);
		stackRaw.updateHeader();
		sprintf(str,"Mean=%f   Min=%f   Max=%f\n",
					stackRaw.m_header.dmean,stackRaw.m_header.dmin,stackRaw.m_header.dmax);
		pThis->TextOutput(str);
		stackRaw.close();
		sprintf(str,"Save Uncorrected Stack to: %s\n",pThis->m_fnStackRaw);
		pThis->TextOutput(str);
	}

	// added by Wen Jiang
	// generate running average frames for CC
	float *hbuf_orig=hbuf;
	float *hbuf_ra=0;
	if(para.nrw>1) {
		sprintf(str,"\nStart generating running average of %d frames\n",para.nrw);
		pThis->TextOutput(str);

		hbuf_ra = new float[sizeb*nframe];  //host memory for entire stack
		memcpy(hbuf_ra, hbuf, sizeof(float)*sizeb*nframe);	// hbuf stores FFT of all frames
		for(int fi = 0; fi<nframe; fi++) {
			sprintf(str,"......Generating runing average of frame %d\n",fi);
			pThis->TextOutput(str);
			for(int ri=0; ri<para.nrw; ri++) {
				int fi2 = fi - para.nrw/2 + ri;
				if(fi2<0 || fi2==fi || fi2>=nframe) continue;
				for(size_t pi=0; pi<sizeb; pi++)
					hbuf_ra[sizeb*fi+pi]+=hbuf[sizeb*fi2+pi];
			}
		}
		hbuf = hbuf_ra;
		sprintf(str,"Running average of %d frames are generated\n\n",para.nrw);
		pThis->TextOutput(str);
	}

	//2. frame to frame shift
	pThis->TextOutput("\nCalculate relative drift between frames\n");
	Matrix<complex<double> > A;
	vector<complex<int> > compList;
	int ncomp=OD_SetEquation_All(A,compList, nframe, para.FrameDistOffset);
	Vector<complex<double> > b=Vector<complex<double> >(ncomp);
	int box=para.CCPeakSearchDim;
	float *hboxmap=new float[box*box*ncomp];
	int par0,par1;
	for(j=0;j<ncomp;j++)
	{
		par0=compList[j].real();
		par1=compList[j].imag();
		//copy to GPU
		GPUMemH2D((void *)dsum,(void *)(hbuf+par0*sizeb),sizeof(float)*sizeb);
		GPUMemH2D((void *)dfft,(void *)(hbuf+par1*sizeb),sizeof(float)*sizeb);
		//shift and cc
		sx=0;
		sy=0;
		GPUShiftCC(dfft, dsum, dPosList,sx, sy, nsam);
		GPUSync();
		//do ifft
		GPUIFFT2d(dfft,ifft_plan);
		GPUSync();
		//find shift
		cc=FindShift(dfft,nsam, hboxmap+j*box*box, box, shiftx, shifty, para.NoisePeakSize-1);
		b[j]=complex<double>(shiftx,shifty);
		avgcc+=cc;
		sprintf(str,"......%03d Frame #%03d VS #%03d xy-shift: %8.4f %8.4f      CC:%f\n",j,par0+para.nStart,par1+para.nStart,shiftx,shifty,cc);
		pThis->TextOutput(str);
	}

	// added by Wen Jiang
	// restore original stack buffer and delete running averages
	hbuf=hbuf_orig;
	if(hbuf_ra) delete[] hbuf_ra;

	//3. sovle overdetermined equation
	Vector<complex<double> > shift=lsSolver(A,b);
	Vector<double> ki=abs(A*shift-b);
	sprintf(str,"\n......ki: First round \n");
	pThis->TextOutput(str);
	for(j=0;j<ki.size();j++)
	{
		par0=compList[j].real();
		par1=compList[j].imag();
		sprintf(str,"......ki #%03d of Frame #%03d VS #%03d: %8.4lf \n",j+para.nStart,par0+para.nStart,par1+para.nStart,ki[j]);
		pThis->TextOutput(str);
	}
	sprintf(str,"................................Average ki: %8.4lf \n\n",sum(ki)/ki.size());
	pThis->TextOutput(str);
	//display CCMap
	if(para.bDispCCMap)
	{
		pThis->CCMapOutput(hboxmap,(void *)&ki);
	}
	//3.1 re-sovle overdetermined equation after removing large ki elments
	double kiThresh=para.kiThresh;
	vector<int> goodlist=OD_Threshold(A, b, ki, kiThresh);
	shift=lsSolver(A,b);
	ki=abs(A*shift-b);
	sprintf(str,"......ki: Second round \n");
	pThis->TextOutput(str);
	for(j=0;j<ki.size();j++)
	{
		par0=compList[goodlist[j] ].real();
		par1=compList[goodlist[j] ].imag();
		sprintf(str,"......ki #%03d of Frame #%03d VS #%03d: %8.4f \n",j+para.nStart,par0+para.nStart,par1+para.nStart,ki[j]);
		pThis->TextOutput(str);
	}
	sprintf(str,"................................Average ki: %8.4lf \n\n",sum(ki)/ki.size());
	pThis->TextOutput(str);

	//output final shift
	//calculate average shift
	double avgshift=0.0;
	for(j=0;j<shift.size();j++) avgshift+=abs(shift[j]);
	avgshift/=shift.size();
	sprintf(str,"Final shift (Average %8.4lf pixels/frame):\n",avgshift);
	//output
	pThis->TextOutput(str);
	vector<complex<double> > shiftlist;
	complex<double> totalshift=0;
	sprintf(str,"......Shift of Frame #%03d : %8.4f %8.4f\n",para.nStart,totalshift.real(),totalshift.imag());
	pThis->TextOutput(str);
	shiftlist.push_back(totalshift);
	for(j=0;j<shift.size();j++)
	{
		totalshift=totalshift+shift[j];
		sprintf(str,"......Shift of Frame #%03d : %8.4f %8.4f\n",j+para.nStart+1,totalshift.real(),totalshift.imag());
		pThis->TextOutput(str);
		shiftlist.push_back(totalshift);
	}
	pThis->PlotOutput(shiftlist);

	//save CCMap image
	if(para.bSaveCCmap) 
	{
		buf2mrc(pThis->m_fnCCmap,hboxmap,box,box,ncomp);
		sprintf(str,"Save CC map to: %s\n",pThis->m_fnCCmap);
		pThis->TextOutput(str);
	}
		

	MRC stackCorr;
	if(para.bSaveStackCorr)
	{
		stackCorr.open(pThis->m_fnStackCorr,"wb");
		stackCorr.m_header.nx=nsam.x;
		stackCorr.m_header.ny=nsam.y;
		stackCorr.m_header.nz=nEndSum-nStartSum+1;
		stackCorr.updateHeader();
	}

	//3. correct xy-shift

	
	//reset memory
	GPUMemZero((void **)&dsum,sizeof(float)*sizeb);
	GPUSync();
	GPUMemZero((void **)&dsumcorr,sizeof(float)*sizeb);
	GPUSync();
	//calculate middle frame shift
	complex<double> midshift=0.0;
	int RefFrame=0;
	if(para.bAlignToMid==1) {
        if(para.nStart > 0 || para.nEnd > 0) {
                RefFrame = para.nStart + (para.nEnd - para.nStart) / 2;
        }
        else {
                RefFrame=nz/2+1;
        }
	}
	if(para.bAlignToMid<=0) RefFrame=abs(para.bAlignToMid);
	if(para.bAlignToMid!=0) 
	{
		if(RefFrame<para.nStart) RefFrame=para.nStart;
		if(RefFrame>para.nEnd) RefFrame=para.nEnd;
		if(para.nStartSum>para.nEnd) para.nStartSum=para.nEnd;
		for(j=0;j<RefFrame-para.nStart;j++) midshift+=shift[j];
	}
	sprintf(str,"\nSum Frame #%03d - #%03d (Reference Frame #%03d):\n",nStartSum+para.nStart,nEndSum+para.nStart,RefFrame);
	pThis->TextOutput(str);

	//Add(copy) first frame to GPU
	totalshift=0;
	for(j=1;j<nStartSum+1;j++)
	{
		totalshift+=shift[j-1];
	}
	GPUMemH2D((void *)dsumcorr,(void *)(hbuf+nStartSum*sizeb),sizeof(float)*sizeb);
	if(para.bAlignToMid) GPUShift(dsumcorr,dPosList,-totalshift.real()+midshift.real(),-totalshift.imag()+midshift.imag(), nsam);
	GPUSync();
	bFSCEven=false;
	sprintf(str,"......Add Frame #%03d with xy shift: %8.4lf %8.4lf\n",nStartSum+para.nStart,-totalshift.real()+midshift.real(),-totalshift.imag()+midshift.imag());
	pThis->TextOutput(str);
	//Save stack
	if(para.bSaveStackCorr)
	{
		GPUMemD2D((void *)dfft,(void *)dsumcorr,sizeof(float)*sizeb);
		GPUIFFT2d(dfft,ifft_plan);
		GPUSync();
		GPUMultiplyNum(dfft,1.0/size,sizeb);
		GPUSync();
		GPUMemD2H((void *)htmp,(void *)dfft,sizeof(float)*sizeb);
		fft2buf(bufmrc,htmp,nsam);
		stackCorr.write2DIm(bufmrc,0);
	}
	//*******
	//sum other frame
	for(j=nStartSum+1;j<=nEndSum;j++)
	{
		totalshift+=shift[j-1];
		
		//copy to GPU
		GPUMemH2D((void *)dfft,(void *)(hbuf+j*sizeb),sizeof(float)*sizeb);
		//shift
		GPUShift(dfft,dPosList,-totalshift.real()+midshift.real(),-totalshift.imag()+midshift.imag(), nsam);
		GPUSync();
		//Sum
		if(bFSCEven) GPUAdd(dsumcorr,dfft,sizeb);
		else GPUAdd(dsum,dfft,sizeb);
		bFSCEven=!bFSCEven;

		sprintf(str,"......Add Frame #%03d with xy shift: %8.4lf %8.4lf\n",j+para.nStart,-totalshift.real()+midshift.real(),-totalshift.imag()+midshift.imag());
		pThis->TextOutput(str);

		//save stack
		if(para.bSaveStackCorr)
		{
			GPUIFFT2d(dfft,ifft_plan);
			GPUSync();
			GPUMultiplyNum(dfft,1.0/size,sizeb);
			GPUSync();
			GPUMemD2H((void *)htmp,(void *)dfft,sizeof(float)*sizeb);
			fft2buf(bufmrc,htmp,nsam);
			stackCorr.write2DIm(bufmrc,j-nStartSum);
		}
	}
	if(para.bSaveStackCorr) 
	{
		MinMaxMean(bufmrc,nsam.x*nsam.y,stackCorr.m_header.dmin, stackCorr.m_header.dmax, stackCorr.m_header.dmean);
	}
	//final sum
	GPUMemD2H((void *)hFSCCorr0,(void *)dsumcorr,sizeof(float)*sizeb);
	GPUMemD2H((void *)hFSCCorr1,(void *)dsum,sizeof(float)*sizeb);
	GPUAdd(dsumcorr,dsum,sizeb);
	GPUSync();

	//copy binned sum to display
	if(para.bDispSumCorr)
	{
		DIM dispdim(DISPDIM,DISPDIM);
		if(nsam.x<nsam.y) dispdim.x=int(DISPDIM*float(nsam.x)/float(nsam.y)+0.5)/2*2;
		if(nsam.x>nsam.y) dispdim.y=int(DISPDIM*float(nsam.y)/float(nsam.x)+0.5)/2*2;
		
		pThis->m_dispdim=dispdim;
		GPUMemBinD2H(hdisp, dsumcorr, dispdim, nsam);
		pThis->ImageOutput(hdisp);
	}

	//copy sum image to host
	float *tsum=dsumcorr;
	GPUIFFT2d(tsum,ifft_plan);
	GPUMultiplyNum(tsum,1.0/size,sizeb);
	GPUMemD2H((void *)hsumCorr,(void *)tsum,sizeof(float)*sizeb);
	fft2buf(bufmrc,hsumCorr,nsam);
	
	//save
	MRC mrc;
	mrc.open(pThis->m_fnAlignsum,"wb");
	mrc.createMRC(bufmrc,nsam.width(),nsam.height(),1);
	//stats
	sprintf(str,"Mean=%f   Min=%f   Max=%f\n",mrc.m_header.dmean,mrc.m_header.dmin,mrc.m_header.dmax);
	pThis->TextOutput(str);
	mrc.close();
	sprintf(str,"Save Corrected Sum to: %s\n",pThis->m_fnAlignsum);
	pThis->TextOutput(str);
	
	//close save Corrected stack
	if(para.bSaveStackCorr) 
	{
		stackCorr.updateHeader();
		pThis->TextOutput("\nWrite corrected stack:\n");
		sprintf(str,"Mean=%f   Min=%f   Max=%f\n",
					stackCorr.m_header.dmean,stackCorr.m_header.dmin,stackCorr.m_header.dmax);
		pThis->TextOutput(str);
		stackCorr.close();
		sprintf(str,"Save Corrected Stack to: %s\n",pThis->m_fnStackCorr);
		pThis->TextOutput(str);
	}

	if(para.bLogFSC)
	{
		complex<double> avgshift=0.0;
		for(i=0;i<shift.size();i++)
		{
			avgshift+=shift[i]/abs(shift[i]);
		}
		pThis->PlotFSC((cuComplex *)hFSCRaw0, (cuComplex *)hFSCRaw1, (cuComplex *)hFSCCorr0, 
					(cuComplex *)hFSCCorr1,hPosList,nsam,avgshift);
	}
	
	
	//free GPU FFT plan, new plan will be created for rectangular image
	//GPUFFTDestroy(fft_plan);
	GPUFFTDestroy(ifft_plan);


	///////////////////////////
	DIM nsamsub=nsam.MinSquare();
	//prepare new fft
	if(para.bDispFFTRaw || para.bDispFFTCorr) fft_plan=GPUFFTPlan(nsamsub);
	//Make Raw fft modulus for display
	if(para.bDispFFTRaw)
	{
		GPUMemH2D((void *)dsum,(void *)hsumRaw,sizeof(float)*sizeb);
		GPURectFFTLogModulus(dfft, dsum, dtmp, dsumcorr, nsam, para.fftscale,fft_plan);
		//copy to host, make pwr image
		GPUMemD2H(htmp,dfft,sizeof(float)*(nsamsub.width()/2+1)*nsamsub.height());
		FFTModulusToDispBuf(htmp,hdisp, nsamsub);
		//copy back to device
		GPUMemH2D(dtmp,hdisp,sizeof(float)*(nsamsub.width()+2)*nsamsub.height());
		//do binning
		GPUBinFFT(dfft, DISPDIM, dtmp, nsamsub, fft_plan);
		GPUMemD2H((void *)hdisp,(void *)dfft,sizeof(float)*(DISPDIM+2)*DISPDIM);
		//display
		pThis->FFTOutputRaw(hdisp); 
	}
	//Make Corrected fft modulus for display
	if(para.bDispFFTCorr)
	{
		GPUMemH2D((void *)dsum,(void *)hsumCorr,sizeof(float)*sizeb);
		GPURectFFTLogModulus(dfft, dsum, dtmp, dsumcorr, nsam, para.fftscale,fft_plan);
		//copy to host, make pwr image
		GPUMemD2H(htmp,dfft,sizeof(float)*(nsamsub.width()/2+1)*nsamsub.height());
		FFTModulusToDispBuf(htmp,hdisp, nsamsub);
		//copy back to device
		GPUMemH2D(dtmp,hdisp,sizeof(float)*(nsamsub.width()+2)*nsamsub.height());
		//do binning
		GPUBinFFT(dfft, DISPDIM, dtmp, nsamsub, fft_plan);
		GPUMemD2H((void *)hdisp,(void *)dfft,sizeof(float)*(DISPDIM+2)*DISPDIM);
		//display
		pThis->FFTOutputCorr(hdisp);   
	}	
	//destory fft
	if(para.bDispFFTRaw || para.bDispFFTCorr) GPUFFTDestroy(fft_plan);
	/////////////////////////////////////////

	
	
	

	delete [] bufmrc;
	delete [] hbuf;
	delete [] hPosList;
	GPUMemFree((void **)&dPosList);
	GPUMemFree((void **)&dsum);
	GPUMemFree((void **)&dsumcorr);
	GPUMemFree((void **)&dfft);
	GPUMemFree((void **)&dtmp);


	delete [] htmp;
	delete [] hboxmap;
	delete [] hdisp;
	delete [] hsumRaw;
	delete [] hsumCorr;
	delete [] hFSCRaw0;
	delete [] hFSCRaw1;
	delete [] hFSCCorr0;
	delete [] hFSCCorr1;

	ResetGPU();
	pThis->Done();
	
	sprintf(str,"Done.\n");
	pThis->TextOutput(str);

	return (void *)0;
}
Пример #18
0
/*
 * LoadData
 *
 * Loads the specified data into the buffer, using the specified formats.
 * Currently, the new format must have the same channel configuration as the
 * original format.
 */
ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc)
{
    enum FmtChannels DstChannels = FmtMono;
    enum FmtType DstType = FmtByte;
    ALuint NewChannels, NewBytes;
    ALuint64 newsize;

    if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE)
        return AL_INVALID_ENUM;
    if((long)SrcChannels != (long)DstChannels)
        return AL_INVALID_ENUM;

    NewChannels = ChannelsFromFmt(DstChannels);
    NewBytes = BytesFromFmt(DstType);

    newsize = frames;
    newsize *= NewBytes;
    newsize *= NewChannels;
    if(newsize > INT_MAX)
        return AL_OUT_OF_MEMORY;

    WriteLock(&ALBuf->lock);
    if(ReadRef(&ALBuf->ref) != 0)
    {
        WriteUnlock(&ALBuf->lock);
        return AL_INVALID_OPERATION;
    }

    /* Round up to the next 16-byte multiple. This could reallocate only when
     * increasing or the new size is less than half the current, but then the
     * buffer's AL_SIZE would not be very reliable for accounting buffer memory
     * usage, and reporting the real size could cause problems for apps that
     * use AL_SIZE to try to get the buffer's play length.
     */
    newsize = (newsize+15) & ~0xf;
    if(newsize != ALBuf->BytesAlloc)
    {
        void *temp = al_calloc(16, (size_t)newsize);
        if(!temp && newsize)
        {
            WriteUnlock(&ALBuf->lock);
            return AL_OUT_OF_MEMORY;
        }
        al_free(ALBuf->data);
        ALBuf->data = temp;
        ALBuf->BytesAlloc = (ALuint)newsize;
    }

    if(data != NULL)
        ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames, align);

    if(storesrc)
    {
        ALBuf->OriginalChannels = SrcChannels;
        ALBuf->OriginalType     = SrcType;
        if(SrcType == UserFmtIMA4)
        {
            ALsizei byte_align = ((align-1)/2 + 4) * ChannelsFromUserFmt(SrcChannels);
            ALBuf->OriginalSize  = frames / align * byte_align;
            ALBuf->OriginalAlign = align;
        }
        else if(SrcType == UserFmtMSADPCM)
        {
            ALsizei byte_align = ((align-2)/2 + 7) * ChannelsFromUserFmt(SrcChannels);
            ALBuf->OriginalSize  = frames / align * byte_align;
            ALBuf->OriginalAlign = align;
        }
        else
        {
            ALBuf->OriginalSize  = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
            ALBuf->OriginalAlign = 1;
        }
    }
    else
    {
        ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels;
        ALBuf->OriginalType     = (enum UserFmtType)DstType;
        ALBuf->OriginalSize     = frames * NewBytes * NewChannels;
        ALBuf->OriginalAlign    = 1;
    }

    ALBuf->Frequency = freq;
    ALBuf->FmtChannels = DstChannels;
    ALBuf->FmtType = DstType;
    ALBuf->Format = NewFormat;

    ALBuf->SampleLen = frames;
    ALBuf->LoopStart = 0;
    ALBuf->LoopEnd = ALBuf->SampleLen;

    WriteUnlock(&ALBuf->lock);
    return AL_NO_ERROR;
}
Пример #19
0
void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device)
{
    ALsfpreset **presets;
    ALsizei num_presets;
    VECTOR(ALbuffer*) buffers;
    ALsizei i;

    VECTOR_INIT(buffers);
    presets = ExchangePtr((XchgPtr*)&self->Presets, NULL);
    num_presets = ExchangeInt(&self->NumPresets, 0);

    for(i = 0;i < num_presets;i++)
    {
        ALsfpreset *preset = presets[i];
        ALfontsound **sounds;
        ALsizei num_sounds;
        ALboolean deleting;
        ALsizei j;

        sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL);
        num_sounds = ExchangeInt(&preset->NumSounds, 0);

        DeletePreset(device, preset);
        preset = NULL;

        for(j = 0;j < num_sounds;j++)
            DecrementRef(&sounds[j]->ref);
        /* Some fontsounds may not be immediately deletable because they're
         * linked to another fontsound. When those fontsounds are deleted
         * they should become deletable, so use a loop until all fontsounds
         * are deleted. */
        do {
            deleting = AL_FALSE;
            for(j = 0;j < num_sounds;j++)
            {
                if(sounds[j] && ReadRef(&sounds[j]->ref) == 0)
                {
                    ALbuffer *buffer;

                    deleting = AL_TRUE;
                    if((buffer=ATOMIC_LOAD(&sounds[j]->Buffer)) != NULL)
                    {
                        ALbuffer **iter;

#define MATCH_BUFFER(_i) (buffer == *(_i))
                        VECTOR_FIND_IF(iter, ALbuffer*, buffers, MATCH_BUFFER);
                        if(iter == VECTOR_ITER_END(buffers))
                            VECTOR_PUSH_BACK(buffers, buffer);
#undef MATCH_BUFFER
                    }
                    DeleteFontsound(device, sounds[j]);
                    sounds[j] = NULL;
                }
            }
        } while(deleting);
        free(sounds);
    }

    ALsoundfont_Destruct(self);
    free(self);

#define DELETE_BUFFER(iter) do {           \
    assert(ReadRef(&(*(iter))->ref) == 0); \
    DeleteBuffer(device, *(iter));         \
} while(0)
    VECTOR_FOR_EACH(ALbuffer*, buffers, DELETE_BUFFER);
#undef DELETE_BUFFER
    VECTOR_DEINIT(buffers);
}
Пример #20
0
/*
 * LoadData
 *
 * Loads the specified data into the buffer, using the specified formats.
 * Currently, the new format must have the same channel configuration as the
 * original format.
 */
ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc)
{
    ALuint NewChannels, NewBytes;
    enum FmtChannels DstChannels;
    enum FmtType DstType;
    ALuint64 newsize;
    ALvoid *temp;

    if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE ||
       (long)SrcChannels != (long)DstChannels)
        return AL_INVALID_ENUM;

    NewChannels = ChannelsFromFmt(DstChannels);
    NewBytes = BytesFromFmt(DstType);

    newsize = frames;
    newsize *= NewBytes;
    newsize *= NewChannels;
    if(newsize > INT_MAX)
        return AL_OUT_OF_MEMORY;

    WriteLock(&ALBuf->lock);
    if(ReadRef(&ALBuf->ref) != 0)
    {
        WriteUnlock(&ALBuf->lock);
        return AL_INVALID_OPERATION;
    }

    temp = realloc(ALBuf->data, (size_t)newsize);
    if(!temp && newsize)
    {
        WriteUnlock(&ALBuf->lock);
        return AL_OUT_OF_MEMORY;
    }
    ALBuf->data = temp;

    if(data != NULL)
        ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames, align);

    if(storesrc)
    {
        ALBuf->OriginalChannels = SrcChannels;
        ALBuf->OriginalType     = SrcType;
        if(SrcType == UserFmtIMA4)
        {
            ALsizei byte_align = ((align-1)/2 + 4) * ChannelsFromUserFmt(SrcChannels);
            ALBuf->OriginalSize  = frames / align * byte_align;
            ALBuf->OriginalAlign = align;
        }
        else if(SrcType == UserFmtMSADPCM)
        {
            ALsizei byte_align = ((align-2)/2 + 7) * ChannelsFromUserFmt(SrcChannels);
            ALBuf->OriginalSize  = frames / align * byte_align;
            ALBuf->OriginalAlign = align;
        }
        else
        {
            ALBuf->OriginalSize  = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
            ALBuf->OriginalAlign = 1;
        }
    }
    else
    {
        ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels;
        ALBuf->OriginalType     = (enum UserFmtType)DstType;
        ALBuf->OriginalSize     = frames * NewBytes * NewChannels;
        ALBuf->OriginalAlign    = 1;
    }

    ALBuf->Frequency = freq;
    ALBuf->FmtChannels = DstChannels;
    ALBuf->FmtType = DstType;
    ALBuf->Format = NewFormat;

    ALBuf->SampleLen = frames;
    ALBuf->LoopStart = 0;
    ALBuf->LoopEnd = ALBuf->SampleLen;

    WriteUnlock(&ALBuf->lock);
    return AL_NO_ERROR;
}
Пример #21
0
// ReadLines
//------------------------------------------------------------------------------
bool TextReader::ReadLines()
{
    for ( ;; )
    {
        // Skip Leading
        AStackString<> token;
        if ( !GetToken( token ) )
        {
            return true;
        }

        // object?
        if ( token == "object" )
        {
            if ( !ReadObject() )
            {
                return false;
            }
            continue;
        }

        // struct?
        if ( token == "struct" )
        {
            if ( !ReadStruct() )
            {
                return false;
            }
            continue;
        }

        // ref?
        if ( token == "ref" )
        {
            if ( !ReadRef() )
            {
                return false;
            }
            continue;
        }

        // children?
        if ( token == "children" )
        {
            if ( !ReadChildren() )
            {
                return false;
            }
            continue;
        }

        // begin object properties?
        if ( token == "{" )
        {
            continue;
        }

        // end object/struct properties?
        if ( token == "}" )
        {
            m_DeserializationStack.Pop();
            continue;
        }

        // assume property
        PropertyType pt;
        pt = GetPropertyTypeFromString( token );
        if ( pt != PT_NONE )
        {
            if ( !ReadProperty( pt ) )
            {
                return false;
            }
            continue;
        }

        if ( token == "weakRef" )
        {
            if ( !ReadWeakRef() )
            {
                return false;
            }
            continue;
        }

        if ( token == "array<" )
        {
            if ( !ReadArray() )
            {
                return false;
            }
            continue;
        }

        if ( token == "arrayOfStruct<" )
        {
            if ( !ReadArrayOfStruct() )
            {
                return false;
            }
            continue;
        }

        Error( "Unkown token" );
        return false;
    }
}