13d4d16f4SPavel Dovgalyuk /* 23d4d16f4SPavel Dovgalyuk * replay-audio.c 33d4d16f4SPavel Dovgalyuk * 43d4d16f4SPavel Dovgalyuk * Copyright (c) 2010-2017 Institute for System Programming 53d4d16f4SPavel Dovgalyuk * of the Russian Academy of Sciences. 63d4d16f4SPavel Dovgalyuk * 73d4d16f4SPavel Dovgalyuk * This work is licensed under the terms of the GNU GPL, version 2 or later. 83d4d16f4SPavel Dovgalyuk * See the COPYING file in the top-level directory. 93d4d16f4SPavel Dovgalyuk * 103d4d16f4SPavel Dovgalyuk */ 113d4d16f4SPavel Dovgalyuk 123d4d16f4SPavel Dovgalyuk #include "qemu/osdep.h" 133d4d16f4SPavel Dovgalyuk #include "qemu/error-report.h" 143d4d16f4SPavel Dovgalyuk #include "sysemu/replay.h" 153d4d16f4SPavel Dovgalyuk #include "replay-internal.h" 163d4d16f4SPavel Dovgalyuk #include "sysemu/sysemu.h" 173d4d16f4SPavel Dovgalyuk #include "audio/audio.h" 183d4d16f4SPavel Dovgalyuk 193d4d16f4SPavel Dovgalyuk void replay_audio_out(int *played) 203d4d16f4SPavel Dovgalyuk { 213d4d16f4SPavel Dovgalyuk if (replay_mode == REPLAY_MODE_RECORD) { 22*d759c951SAlex Bennée g_assert(replay_mutex_locked()); 233d4d16f4SPavel Dovgalyuk replay_save_instructions(); 243d4d16f4SPavel Dovgalyuk replay_put_event(EVENT_AUDIO_OUT); 253d4d16f4SPavel Dovgalyuk replay_put_dword(*played); 263d4d16f4SPavel Dovgalyuk } else if (replay_mode == REPLAY_MODE_PLAY) { 27*d759c951SAlex Bennée g_assert(replay_mutex_locked()); 283d4d16f4SPavel Dovgalyuk replay_account_executed_instructions(); 293d4d16f4SPavel Dovgalyuk if (replay_next_event_is(EVENT_AUDIO_OUT)) { 303d4d16f4SPavel Dovgalyuk *played = replay_get_dword(); 313d4d16f4SPavel Dovgalyuk replay_finish_event(); 323d4d16f4SPavel Dovgalyuk } else { 333d4d16f4SPavel Dovgalyuk error_report("Missing audio out event in the replay log"); 343d4d16f4SPavel Dovgalyuk abort(); 353d4d16f4SPavel Dovgalyuk } 363d4d16f4SPavel Dovgalyuk } 373d4d16f4SPavel Dovgalyuk } 383d4d16f4SPavel Dovgalyuk 393d4d16f4SPavel Dovgalyuk void replay_audio_in(int *recorded, void *samples, int *wpos, int size) 403d4d16f4SPavel Dovgalyuk { 413d4d16f4SPavel Dovgalyuk int pos; 423d4d16f4SPavel Dovgalyuk uint64_t left, right; 433d4d16f4SPavel Dovgalyuk if (replay_mode == REPLAY_MODE_RECORD) { 44*d759c951SAlex Bennée g_assert(replay_mutex_locked()); 453d4d16f4SPavel Dovgalyuk replay_save_instructions(); 463d4d16f4SPavel Dovgalyuk replay_put_event(EVENT_AUDIO_IN); 473d4d16f4SPavel Dovgalyuk replay_put_dword(*recorded); 483d4d16f4SPavel Dovgalyuk replay_put_dword(*wpos); 493d4d16f4SPavel Dovgalyuk for (pos = (*wpos - *recorded + size) % size ; pos != *wpos 503d4d16f4SPavel Dovgalyuk ; pos = (pos + 1) % size) { 513d4d16f4SPavel Dovgalyuk audio_sample_to_uint64(samples, pos, &left, &right); 523d4d16f4SPavel Dovgalyuk replay_put_qword(left); 533d4d16f4SPavel Dovgalyuk replay_put_qword(right); 543d4d16f4SPavel Dovgalyuk } 553d4d16f4SPavel Dovgalyuk } else if (replay_mode == REPLAY_MODE_PLAY) { 56*d759c951SAlex Bennée g_assert(replay_mutex_locked()); 573d4d16f4SPavel Dovgalyuk replay_account_executed_instructions(); 583d4d16f4SPavel Dovgalyuk if (replay_next_event_is(EVENT_AUDIO_IN)) { 593d4d16f4SPavel Dovgalyuk *recorded = replay_get_dword(); 603d4d16f4SPavel Dovgalyuk *wpos = replay_get_dword(); 613d4d16f4SPavel Dovgalyuk for (pos = (*wpos - *recorded + size) % size ; pos != *wpos 623d4d16f4SPavel Dovgalyuk ; pos = (pos + 1) % size) { 633d4d16f4SPavel Dovgalyuk left = replay_get_qword(); 643d4d16f4SPavel Dovgalyuk right = replay_get_qword(); 653d4d16f4SPavel Dovgalyuk audio_sample_from_uint64(samples, pos, left, right); 663d4d16f4SPavel Dovgalyuk } 673d4d16f4SPavel Dovgalyuk replay_finish_event(); 683d4d16f4SPavel Dovgalyuk } else { 693d4d16f4SPavel Dovgalyuk error_report("Missing audio in event in the replay log"); 703d4d16f4SPavel Dovgalyuk abort(); 713d4d16f4SPavel Dovgalyuk } 723d4d16f4SPavel Dovgalyuk } 733d4d16f4SPavel Dovgalyuk } 74