Beispiel #1
0
Clump *LoaderDFF::loadFromMemory(FileHandle file) {
    auto model = new Clump;

    RWBStream rootStream(file->data, file->length);

    auto rootID = rootStream.getNextChunk();
    if (rootID != CHUNK_CLUMP) {
        throw DFFLoaderException("Invalid root section ID " +
                                 std::to_string(rootID));
    }

    RWBStream modelStream = rootStream.getInnerStream();
    auto rootStructID = modelStream.getNextChunk();
    if (rootStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Clump missing struct chunk");
    }

    // There is only one value in the struct section.
    auto numAtomics = *(std::uint32_t *)rootStream.getCursor();
    RW_UNUSED(numAtomics);

    GeometryList geometrylist;
    FrameList framelist;

    // Process everything inside the clump stream.
    RWBStream::ChunkID chunkID;
    while ((chunkID = modelStream.getNextChunk())) {
        switch (chunkID) {
            case CHUNK_FRAMELIST:
                framelist = readFrameList(modelStream);
                break;
            case CHUNK_GEOMETRYLIST:
                geometrylist = readGeometryList(modelStream);
                break;
            case CHUNK_ATOMIC: {
                auto atomic = readAtomic(framelist, geometrylist, modelStream);
                RW_CHECK(atomic, "Failed to read atomic");
                if (!atomic) {
                    // Abort reading the rest of the clump
                    return nullptr;
                }
                model->addAtomic(atomic);
            } break;
            default:
                break;
        }
    }

    if (!framelist.empty()) {
        model->setFrame(framelist[0]);
    }

    // Ensure the model has cached metrics
    model->recalculateMetrics();

    return model;
}
void EMUUSBInputStream::readCompleted ( void * frameListNrPtr,
                                       IOReturn result, IOUSBLowLatencyIsocFrame * pFrames) {
    
    // HACK we have numUSBFramesPerList frames, which one to check?? Print frame 0 info.
    debugIOLogR("+ readCompleted framelist %d  result %x ", currentFrameList, result);
    
    
    startingEngine = FALSE; // HACK this is old code...
    
    /*An "underrun error" occurs when the UART transmitter has completed sending a character and the transmit buffer is empty. In asynchronous modes this is treated as an indication that no data remains to be transmitted, rather than an error, since additional stop bits can be appended. This error indication is commonly found in USARTs, since an underrun is more serious in synchronous systems.
     */
    
	if (kIOReturnAborted != result) {
        GatherInputSamples(); // also check if there is more in the buffer. 
	}
	
    // Data collection from the USB read is complete.
    // Now start the read on the next block.
	if (!shouldStop) {
        
		// (orig doc) keep incrementing until limit of numUSBFrameLists - 1 is reached.
        // also, we can wonder if we want to do it this way. Why not just check what comes in instead
        nextCompleteFrameList =(nextCompleteFrameList + 1) % RECORD_NUM_USB_FRAME_LISTS;
        
        // now we have already numUSBFrameListsToQueue-1 other framelist queues running.
        // We set our current list to the next one that is not yet running
        // CHECK can we just use ALL framelists instead of queueing only part of them?
        
        UInt32 frameListToRead = nextCompleteFrameList - 1 + numUSBFrameListsToQueue;
        frameListToRead -= numUSBFrameLists * (frameListToRead >= numUSBFrameLists);// crop the number of framesToRead
        // seems something equal to frameListToRead = (frameListnr + usbstream->numUSBFrameListsToQueue) % usbstream->numUSBFrameLists;
        readFrameList(frameListToRead); // restart reading (but for different framelist).
        
	} else  {
		debugIOLogR("++EMUUSBAudioEngine::readCompleted() - stopped: %d", shouldStop);
		shouldStop++;
	}
    
    if (shouldStop > RECORD_NUM_USB_FRAME_LISTS) {
        debugIOLogC("EMUUSBInputStream::readCompleted all input streams stopped");
        started = false;
        notifyClosed();
    }

// HACK attempt to read feedback from device.
//    if (counter++==100) {
//
//        CheckForAssociatedEndpoint( interfaceNumber, alternateSettingID);
//    }
    
	debugIOLogR("- readCompleted currentFrameList=%d",currentFrameList);
	return;
}
IOReturn EMUUSBInputStream::start(UInt64 startFrameNr) {
    ReturnIf(!initialized, kIOReturnNotReady);
    ReturnIf(startFrameNr < streamInterface->GetDevice()->GetBus()->GetFrameNumber() + 10, kIOReturnTimeout);
    ReturnIfFail(StreamInfo::reset());
    ReturnIfFail(StreamInfo::start(startFrameNr));

    shouldStop = 0;
    nextCompleteFrameList = 0;
    previousFrameList = 3; //  different from currentFrameList.
    currentReadList = nextCompleteFrameList;
    mDropStartingFrames = kNumberOfStartingFramesToDrop;

    // we start reading on all framelists. USB will figure it out and take the next one in order
    // when it has data. We restart each framelist in readCompleted when we get data.
    // this restarting may take some time.
	for (UInt32 frameListNum = nextCompleteFrameList; frameListNum < numUSBFrameListsToQueue; ++frameListNum) {
		readFrameList(frameListNum);         // FIXME handle failed call
	}
    started = true;
    return kIOReturnSuccess;
}