if (pDevice == NULL) return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called with invalid arguments (pDevice == NULL).", MAL_INVALID_ARGS);
if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called for an uninitialized device.", MAL_DEVICE_NOT_INITIALIZED);
if (pDevice == NULL) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called with invalid arguments (pDevice == NULL).", MAL_INVALID_ARGS);
}
if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called for an uninitialized device.", MAL_DEVICE_NOT_INITIALIZED);
}
mal_result result = MAL_ERROR;
mal_mutex_lock(&pDevice->lock);
{
// Be a bit more descriptive if the device is already started or is already in the process of starting. This is likely
// a bug with the application.
if (mal_device__get_state(pDevice) == MAL_STATE_STARTING) {
mal_mutex_unlock(&pDevice->lock);
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called while another thread is already starting it.", MAL_DEVICE_ALREADY_STARTING);
}
if (mal_device__get_state(pDevice) == MAL_STATE_STARTED) {
mal_mutex_unlock(&pDevice->lock);
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called for a device that's already started.", MAL_DEVICE_ALREADY_STARTED);
}
// The device needs to be in a stopped state. If it's not, we just let the caller know the device is busy.
if (mal_device__get_state(pDevice) != MAL_STATE_STOPPED) {
mal_mutex_unlock(&pDevice->lock);
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_start() called while another thread is in the process of stopping it.", MAL_DEVICE_BUSY);
}
// Starting, stopping and pausing are wrapped in a mutex which means we can assert that the device is in a stopped or paused state.
if (pDevice == NULL) return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called with invalid arguments (pDevice == NULL).", MAL_INVALID_ARGS);
if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called for an uninitialized device.", MAL_DEVICE_NOT_INITIALIZED);
if (pDevice == NULL) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called with invalid arguments (pDevice == NULL).", MAL_INVALID_ARGS);
}
if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) {
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called for an uninitialized device.", MAL_DEVICE_NOT_INITIALIZED);
}
mal_result result = MAL_ERROR;
mal_mutex_lock(&pDevice->lock);
{
// Be a bit more descriptive if the device is already stopped or is already in the process of stopping. This is likely
// a bug with the application.
if (mal_device__get_state(pDevice) == MAL_STATE_STOPPING) {
mal_mutex_unlock(&pDevice->lock);
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called while another thread is already stopping it.", MAL_DEVICE_ALREADY_STOPPING);
}
if (mal_device__get_state(pDevice) == MAL_STATE_STOPPED) {
mal_mutex_unlock(&pDevice->lock);
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called for a device that's already stopped.", MAL_DEVICE_ALREADY_STOPPED);
}
// The device needs to be in a started state. If it's not, we just let the caller know the device is busy.
if (mal_device__get_state(pDevice) != MAL_STATE_STARTED) {
mal_mutex_unlock(&pDevice->lock);
return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "mal_device_stop() called while another thread is in the process of starting it.", MAL_DEVICE_BUSY);
}
// Starting, stopping and pausing are wrapped in a mutex which means we can assert that the device is in a started or paused state.