/*! \internal Called by LoadAnimationClipJob on the threadpool */ void AnimationClip::loadAnimation() { qCDebug(Jobs) << Q_FUNC_INFO << m_source; clearData(); // Load the data switch (m_dataType) { case File: loadAnimationFromUrl(); break; case Data: loadAnimationFromData(); break; default: Q_UNREACHABLE(); } // Update the duration const float t = findDuration(); setDuration(t); m_channelComponentCount = findChannelComponentCount(); // If using a loader inform the frontend of the status change if (m_source.isEmpty()) { if (qFuzzyIsNull(t) || m_channelComponentCount == 0) setStatus(QAnimationClipLoader::Error); else setStatus(QAnimationClipLoader::Ready); } // notify all ClipAnimators and BlendedClipAnimators that depend on this clip, // that the clip has changed and that they are now dirty { QMutexLocker lock(&m_mutex); for (const Qt3DCore::QNodeId id : qAsConst(m_dependingAnimators)) { ClipAnimator *animator = m_handler->clipAnimatorManager()->lookupResource(id); if (animator) animator->animationClipMarkedDirty(); } for (const Qt3DCore::QNodeId id : qAsConst(m_dependingBlendedAnimators)) { BlendedClipAnimator *animator = m_handler->blendedClipAnimatorManager()->lookupResource(id); if (animator) animator->animationClipMarkedDirty(); } m_dependingAnimators.clear(); m_dependingBlendedAnimators.clear(); } qCDebug(Jobs) << "Loaded animation data:" << *this; }
/** Cuts the file from firstMark to lastMark (inclusively) out of the sampleData from data Also updates the duration and number of samples contained in data **/ void cut(File_Data* data, int firstMark, int lastMark){ int i, j; int samp = 0; if(firstMark > lastMark){ int temp = firstMark; firstMark = lastMark; lastMark = temp; } for(i = 0; i < data->samples; i++){ if(i >= firstMark && i <= lastMark){ continue; } for(j = 0; j < data->channels; j++){ data->sampleData[samp][j] = data->sampleData[i][j]; } samp++; } data->samples = samp; strcpy(findDuration(data->sampleRate, data->channels, data->samples, data->duration), data->duration); }
/** Processes the whole CS229 file starting after the "CS229 at the top of the file" Thie will call processHeader and getSamplesCS229 to process the data of the file **/ File_Data processCS229(FILE *file) { char line[MAX_LINE_LENGTH]; File_Data data; strncpy(data.format, "CS229\0", 6); data.samples = -1; data.channels = -1; data.sampleRate = -1; data.bitDepth = -1; processHeader(file, &data); if(data.success == 0) { fprintf(stderr, "Error reading header.\n"); exit(EXIT_FAILURE); } getSamplesCS229(file, &data); if(data.sampleRate < 0 || data.bitDepth < 0 || data.channels < 0 || data.channels > 32 || (data.bitDepth != 8 && data.bitDepth != 16 && data.bitDepth != 32)) { data.success = 0; } else { data.success = 1; strcpy(data.duration, findDuration(data.sampleRate, data.channels, data.samples, data.duration)); } return data; }
/** Process the AIFF file. This method will call processCOMM to handle the COMM section. It will mark the position of the sound file so processSSND and getSamplesAIFF can perform correctly. **/ File_Data processAIFF(FILE *outfile, FILE* infile){ int foundComm = 0; int foundSSND = 0; File_Data data; CommonChunk comm; SoundDataChunk sdc; data.samples = -1; data.channels = -1; data.sampleRate = -1; data.bitDepth = -1; data.success = 0; char buff[4]; int i, j; for(i = 0; i < 4; i++){ buff[i] = fgetc(infile); } flipBytes(buff, 4); int y = *((int*)buff); for(i = 0; i < 4; i++){ buff[i] = fgetc(infile); } if(strncmp(buff, "AIFF", 4) != 0){ data.success = 0; return data; }else { strncpy(data.format, "AIFF\0", 5); } while(!foundComm || !foundSSND){ buff[0] = fgetc(infile); if(EOF == buff[0]){ data.success = 0; return data; }else if(buff[0] != 'C' && buff[0] != 'S' && buff[0] != 'A'){ continue; } for(i = 1; i < 4; i++){ buff[i] = fgetc(infile); if(buff[i] == 'C'){ ungetc(buff[i], infile); continue; } } if(strncmp(buff, "COMM", 4) == 0){ comm = processComm(infile); data.samples = comm.numSampleFrames; data.channels = comm.numChannels; data.sampleRate = comm.sampleRate; data.bitDepth = comm.sampleSize; strcpy(data.duration, findDuration(data.sampleRate, data.channels, data.samples, data.duration)); foundComm = 1; } if(strncmp(buff, "SSND", 4) == 0){ /*Marks the position of the SSND chunk so it can be processed later*/ foundSoundData = fgetpos(infile, &SSNDLocation); foundSSND = 1; } if(strncmp(buff, "COMT", 4) == 0 || strncmp(buff, "ANNO", 4) == 0 ){ /* Runs through comment chunks */ int chunkSize; char sizeBuff[4]; for(j = 0; j < 4; j++){ sizeBuff[j] = fgetc(infile); } flipBytes(sizeBuff, 4); chunkSize = *((int *)sizeBuff); int count = 0; while(count < chunkSize){ count++; fgetc(infile); } } } if(foundSSND && foundComm) data.success = 1; return data; }