Exemplo n.º 1
0
MediaBuffer* MidiEngine::readBuffer() {
    EAS_STATE state;
    EAS_State(mEasData, mEasHandle, &state);
    if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
        return NULL;
    }
    MediaBuffer *buffer;
    status_t err = mGroup->acquire_buffer(&buffer);
    if (err != OK) {
        ALOGE("readBuffer: no buffer");
        return NULL;
    }
    EAS_I32 timeMs;
    EAS_GetLocation(mEasData, mEasHandle, &timeMs);
    int64_t timeUs = 1000ll * timeMs;
    buffer->meta_data()->setInt64(kKeyTime, timeUs);

    EAS_PCM* p = (EAS_PCM*) buffer->data();
    int numBytesOutput = 0;
    for (int i = 0; i < NUM_COMBINE_BUFFERS; i++) {
        EAS_I32 numRendered;
        EAS_RESULT result = EAS_Render(mEasData, p, mEasConfig->mixBufferSize, &numRendered);
        if (result != EAS_SUCCESS) {
            ALOGE("EAS_Render returned %ld", result);
            break;
        }
        p += numRendered * mEasConfig->numChannels;
        numBytesOutput += numRendered * mEasConfig->numChannels * sizeof(EAS_PCM);
    }
    buffer->set_range(0, numBytesOutput);
    ALOGV("readBuffer: returning %zd in buffer %p", buffer->range_length(), buffer);
    return buffer;
}
Exemplo n.º 2
0
MIDI_RESULT MIDI_State(MIDI_HANDLE handle, MIDI_STATE *state)
{
    EAS_RESULT result;

    // lock
    pthread_mutex_lock(&mutex);

    // check stream state
    if ((result = EAS_State(pEASData, handle, state)) != EAS_SUCCESS)
    {
        // unlock
        pthread_mutex_unlock(&mutex);      
	return result;
    }

    // unlock
    pthread_mutex_unlock(&mutex);

    return MIDI_SUCCESS;
}
int MidiFile::render() {
    EAS_RESULT result = EAS_FAILURE;
    EAS_I32 count;
    int temp;
    bool audioStarted = false;

    ALOGV("MidiFile::render");

    // allocate render buffer
    mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS];
    if (!mAudioBuffer) {
        ALOGE("mAudioBuffer allocate failed");
        goto threadExit;
    }

    // signal main thread that we started
    {
        Mutex::Autolock l(mMutex);
        mTid = gettid();
        ALOGV("render thread(%d) signal", mTid);
        mCondition.signal();
    }

    while (1) {
        mMutex.lock();

        // nothing to render, wait for client thread to wake us up
        while (!mRender && !mExit)
        {
            ALOGV("MidiFile::render - signal wait");
            mCondition.wait(mMutex);
            ALOGV("MidiFile::render - signal rx'd");
        }
        if (mExit) {
            mMutex.unlock();
            break;
        }

        // render midi data into the input buffer
        //ALOGV("MidiFile::render - rendering audio");
        int num_output = 0;
        EAS_PCM* p = mAudioBuffer;
        for (int i = 0; i < NUM_BUFFERS; i++) {
            result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count);
            if (result != EAS_SUCCESS) {
                ALOGE("EAS_Render returned %ld", result);
            }
            p += count * pLibConfig->numChannels;
            num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
        }

        // update playback state and position
        // ALOGV("MidiFile::render - updating state");
        EAS_GetLocation(mEasData, mEasHandle, &mPlayTime);
        EAS_State(mEasData, mEasHandle, &mState);
        mMutex.unlock();

        // create audio output track if necessary
        if (!mAudioSink->ready()) {
            ALOGV("MidiFile::render - create output track");
            if (createOutputTrack() != NO_ERROR)
                goto threadExit;
        }

        // Write data to the audio hardware
        // ALOGV("MidiFile::render - writing to audio output");
        if ((temp = mAudioSink->write(mAudioBuffer, num_output)) < 0) {
            ALOGE("Error in writing:%d",temp);
            return temp;
        }

        // start audio output if necessary
        if (!audioStarted) {
            //ALOGV("MidiFile::render - starting audio");
            mAudioSink->start();
            audioStarted = true;
        }

        // still playing?
        if ((mState == EAS_STATE_STOPPED) || (mState == EAS_STATE_ERROR) ||
                (mState == EAS_STATE_PAUSED))
        {
            switch(mState) {
            case EAS_STATE_STOPPED:
            {
                ALOGV("MidiFile::render - stopped");
                mPlayTime = mDuration;
                sendEvent(MEDIA_PLAYBACK_COMPLETE);
                break;
            }
            case EAS_STATE_ERROR:
            {
                ALOGE("MidiFile::render - error");
                sendEvent(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN);
                break;
            }
            case EAS_STATE_PAUSED:
                ALOGV("MidiFile::render - paused");
                break;
            default:
                break;
            }
            mAudioSink->stop();
            audioStarted = false;
            mRender = false;
        }
    }

threadExit:
    mAudioSink.clear();
    if (mAudioBuffer) {
        delete [] mAudioBuffer;
        mAudioBuffer = NULL;
    }
    mMutex.lock();
    mTid = -1;
    mCondition.signal();
    mMutex.unlock();
    return result;
}
static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
{
	EAS_HANDLE handle;
	EAS_RESULT result, reportResult;
	EAS_I32 count;
	EAS_STATE state;
	EAS_I32 playTime;
	char waveFilename[256];
	WAVE_FILE *wFile;
	EAS_INT i;
	EAS_PCM *p;
	EAS_FILE file;

	/* determine the name of the output file */
	wFile = NULL;
	if (outputFile == NULL)
	{
		StrCopy(waveFilename, filename, sizeof(waveFilename));
		if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
		{
			{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
			return EAS_FAILURE;
		}
		outputFile = waveFilename;
	}

	/* call EAS library to open file */
	file.path = filename;
	file.fd = 0;
	if ((reportResult = EAS_OpenFile(easData, &file, &handle)) != EAS_SUCCESS)
	{
		{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
		return reportResult;
	}

	/* prepare to play the file */
	if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
	{
		{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
		reportResult = result;
	}

	/* get play length */
	if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
	{
		{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
		return result;
	}
	EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);

	if (reportResult == EAS_SUCCESS)
	{
		/* create the output file */
		wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
		if (!wFile)
		{
			{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
			reportResult = EAS_FAILURE;
		}
	}

	/* rendering loop */
	while (reportResult == EAS_SUCCESS)
	{

		/* we may render several buffers here to fill one host buffer */
		for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
		{
			
			/* get the current time */
			if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
			{
				{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
				if (reportResult == EAS_SUCCESS)
					reportResult = result;
				break;
			}
			{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }

			/* render a buffer of audio */
			if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
			{
				{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
				if (reportResult == EAS_SUCCESS)
					reportResult = result;
			}
		}

		if (result == EAS_SUCCESS)
		{
			/* write it to the wave file */
			if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
			{
				{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
				reportResult = EAS_FAILURE;
			}
		}

		if (reportResult == EAS_SUCCESS)
		{
			/* check stream state */
			if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
			{
				{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
				reportResult = result;
			}

			/* is playback complete */
			if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
				break;
		}
	}

	/* close the output file */
	if (wFile)
	{
		if (!WaveFileClose(wFile))
		{
			{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
			if (reportResult == EAS_SUCCESS)
				result = EAS_FAILURE;
		}
	}
	
	/* close the input file */
	if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
	{
		{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
		if (reportResult == EAS_SUCCESS)
			result = EAS_FAILURE;
	}

	return reportResult;
} /* end PlayFile */