void mitk::ImageChannelSelector::GenerateData() { const Image::RegionType& requestedRegion = GetOutput()->GetRequestedRegion(); //do we really need the complete channel? if(requestedRegion.GetSize(3)>1) SetChannelItem(GetChannelData(m_ChannelNr), 0); else //or only a complete volume at a time? if(requestedRegion.GetSize(2)>1) SetVolumeItem(GetVolumeData(requestedRegion.GetIndex(3), m_ChannelNr), requestedRegion.GetIndex(3), 0); else //not even a complete volume, so now take just a slice! SetSliceItem(GetSliceData(requestedRegion.GetIndex(2), requestedRegion.GetIndex(3), m_ChannelNr), requestedRegion.GetIndex(2), requestedRegion.GetIndex(3), 0); }
void* mitk::Image::GetData() { if(m_Initialized==false) { if(GetSource().IsNull()) return NULL; if(GetSource()->Updating()==false) GetSource()->UpdateOutputInformation(); } m_CompleteData=GetChannelData(); // update channel's data // if data was not available at creation point, the m_Data of channel descriptor is NULL // if data present, it won't be overwritten m_ImageDescriptor->GetChannelDescriptor(0).SetData(m_CompleteData->GetData()); return m_CompleteData->GetData(); }
bool mitk::Image::SetImportChannel(void *data, int n, ImportMemoryManagementType importMemoryManagement) { if(IsValidChannel(n)==false) return false; // channel descriptor const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ImageDataItemPointer ch; if(IsChannelSet(n)) { ch=GetChannelData(n,data,importMemoryManagement); if(ch->GetManageMemory()==false) { ch=AllocateChannelData(n,data,importMemoryManagement); if(ch.GetPointer()==NULL) return false; } if ( ch->GetData() != data ) std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize)); ch->Modified(); ch->SetComplete(true); //we have changed the data: call Modified()! Modified(); } else { ch=AllocateChannelData(n,data,importMemoryManagement); if(ch.GetPointer()==NULL) return false; if ( ch->GetData() != data ) std::memcpy(ch->GetData(), data, m_OffsetTable[4]*(ptypeSize)); ch->SetComplete(true); this->m_ImageDescriptor->GetChannelDescriptor(n).SetData( ch->GetData() ); //we just added a missing Channel, which is not regarded as modification. //Therefore, we do not call Modified()! } return true; }
mitk::Image::ImageDataItemPointer mitk::Image::GetChannelData(int n, void *data, ImportMemoryManagementType importMemoryManagement) { if(IsValidChannel(n)==false) return NULL; ImageDataItemPointer ch, vol; ch=m_Channels[n]; if((ch.GetPointer()!=NULL) && (ch->IsComplete())) return ch; // let's see if all volumes are set, so that we can (could) combine them to a channel if(IsChannelSet(n)) { // if there is only one time frame we do not need to combine anything if(m_Dimensions[3]<=1) { vol=GetVolumeData(0,n,data,importMemoryManagement); ch=new ImageDataItem(*vol, m_ImageDescriptor, m_ImageDescriptor->GetNumberOfDimensions(), data, importMemoryManagement == ManageMemory); ch->SetComplete(true); } else { const size_t ptypeSize = this->m_ImageDescriptor->GetChannelTypeById(n).GetSize(); ch=m_Channels[n]; // ok, let's combine the volumes! if(ch.GetPointer()==NULL) ch=new ImageDataItem(this->m_ImageDescriptor, NULL, true); ch->SetComplete(true); size_t size=m_OffsetTable[m_Dimension-1]*(ptypeSize); unsigned int t; ImageDataItemPointerArray::iterator slicesIt = m_Slices.begin()+n*m_Dimensions[2]*m_Dimensions[3]; for(t=0;t<m_Dimensions[3];++t) { int posVol; ImageDataItemPointer vol; posVol=GetVolumeIndex(t,n); vol=GetVolumeData(t,n,data,importMemoryManagement); if(vol->GetParent()!=ch) { // copy data of volume in channel size_t offset = ((size_t) t)*m_OffsetTable[3]*(ptypeSize); std::memcpy(static_cast<char*>(ch->GetData())+offset, vol->GetData(), size); // REVEIW FIX mitkIpPicDescriptor * pic = vol->GetPicDescriptor(); // replace old volume with reference to channel vol=new ImageDataItem(*ch, m_ImageDescriptor, 3, data, importMemoryManagement == ManageMemory, offset); vol->SetComplete(true); //mitkIpFuncCopyTags(vol->GetPicDescriptor(), pic); m_Volumes[posVol]=vol; // get rid of slices - they may point to old volume ImageDataItemPointer dnull=NULL; for(unsigned int i = 0; i < m_Dimensions[2]; ++i, ++slicesIt) { assert(slicesIt != m_Slices.end()); *slicesIt = dnull; } } } // REVIEW FIX // if(ch->GetPicDescriptor()->info->tags_head==NULL) // mitkIpFuncCopyTags(ch->GetPicDescriptor(), m_Volumes[GetVolumeIndex(0,n)]->GetPicDescriptor()); } return m_Channels[n]=ch; } // channel is unavailable. Can we calculate it? if((GetSource().IsNotNull()) && (GetSource()->Updating()==false)) { // ... wir muessen rechnen!!! .... m_RequestedRegion.SetIndex(0, 0); m_RequestedRegion.SetIndex(1, 0); m_RequestedRegion.SetIndex(2, 0); m_RequestedRegion.SetIndex(3, 0); m_RequestedRegion.SetIndex(4, n); m_RequestedRegion.SetSize(0, m_Dimensions[0]); m_RequestedRegion.SetSize(1, m_Dimensions[1]); m_RequestedRegion.SetSize(2, m_Dimensions[2]); m_RequestedRegion.SetSize(3, m_Dimensions[3]); m_RequestedRegion.SetSize(4, 1); m_RequestedRegionInitialized=true; GetSource()->Update(); // did it work? if(IsChannelSet(n)) //yes: now we can call ourselves without the risk of a endless loop (see "if" above) return GetChannelData(n,data,importMemoryManagement); else return NULL; } else { ImageDataItemPointer item = AllocateChannelData(n,data,importMemoryManagement); item->SetComplete(true); return item; } }
void SoundLibrary3dSoftware::Callback(StereoSample *_buf, unsigned int _numSamples) { if (!m_channels) return; #ifdef INVOKE_CALLBACK_FROM_SOUND_THREAD // SoundInstances in the SoundSystem will access our channels directly, so lock // it out while we're running. NetLockMutex lock( g_app->m_soundSystem->m_mutex ); #endif double duration = (double)_numSamples / (double)g_soundLibrary2d->m_freq; GetChannelData(duration); ApplyDspFX(duration); m_profiler->StartProfile( "Mix"); memset(m_left, 0, sizeof(float) * _numSamples); memset(m_right, 0, sizeof(float) * _numSamples); // Merge all the channel's into one stereo stream, converting to floats to // prevent overflows and reap the benefits of huge FPU power on Athlons // and modern Pentiums. for (int i = 0; i < m_numChannels; ++i) { float volLeft, volRight; CalcChannelVolumes(i, &volLeft, &volRight); float deltaVolLeft = 0.0f; float deltaVolRight = 0.0f; if (m_channels[i].m_forceVolumeJump) { deltaVolLeft = volLeft - m_channels[i].m_oldVolLeft; deltaVolRight = volRight - m_channels[i].m_oldVolRight; } m_channels[i].m_forceVolumeJump = false; float const maxDelta = 0.003f; // Skip this channel if it contains silence if (!m_channels[i].m_containsSilence) { float relativeFreq = (float)m_channels[i].m_freq / (float)g_soundLibrary2d->m_freq; signed short *inBuf = m_channels[i].m_buffer; // Determine which mixer function to use - some are faster than others if (fabsf(deltaVolLeft) < maxDelta && fabsf(deltaVolRight) < maxDelta) { if (NearlyEquals(relativeFreq, 1.0f)) { MixSameFreqFixedVol(inBuf, _numSamples, volLeft, volRight); } else { MixDiffFreqFixedVol(inBuf, _numSamples, volLeft, volRight, relativeFreq); } } else { if (NearlyEquals(relativeFreq, 1.0f)) { MixSameFreqRampVol(inBuf, _numSamples, m_channels[i].m_oldVolLeft, m_channels[i].m_oldVolRight, volLeft, volRight); } else { MixDiffFreqRampVol(inBuf, _numSamples, m_channels[i].m_oldVolLeft, m_channels[i].m_oldVolRight, volLeft, volRight, relativeFreq); } } } m_channels[i].m_oldVolLeft = volLeft; m_channels[i].m_oldVolRight = volRight; } // Scan the left and right floating point versions of the output buffer to // find the largest sample float largest = 0.0f; for (int i = 0; i < _numSamples; ++i) { if (fabsf(m_left[i]) > largest) largest = fabsf(m_left[i]); if (fabsf(m_right[i]) > largest) largest = fabsf(m_right[i]); } // Convert the stereo stream from floats back to signed shorts float scale = 1.0f; if (largest > 32766) { scale = 32766.0f / largest; } if (scale > 1.0f) { scale = 1.0f; } for (int i = 0; i < _numSamples; ++i) { _buf[i].m_left = Round(m_left[i] * scale); _buf[i].m_right = Round(m_right[i] * scale); } m_profiler->EndProfile( "Mix"); }