diff --git a/src/tests/kits/game/Jamfile b/src/tests/kits/game/Jamfile index c878beddff..a88eba4973 100644 --- a/src/tests/kits/game/Jamfile +++ b/src/tests/kits/game/Jamfile @@ -1,11 +1,12 @@ SubDir HAIKU_TOP src tests kits game ; -SubInclude HAIKU_TOP src tests kits game file_game_sound_test ; -SubInclude HAIKU_TOP src tests kits game set_mouse_position_test ; -SubInclude HAIKU_TOP src tests kits game simple_game_sound_test ; +SubInclude HAIKU_TOP src tests kits game chart ; SubInclude HAIKU_TOP src tests kits game direct_window_test ; SubInclude HAIKU_TOP src tests kits game direct_window_info_test ; +SubInclude HAIKU_TOP src tests kits game file_game_sound_test ; +SubInclude HAIKU_TOP src tests kits game push_game_sound_test ; +SubInclude HAIKU_TOP src tests kits game set_mouse_position_test ; +SubInclude HAIKU_TOP src tests kits game simple_game_sound_test ; SubInclude HAIKU_TOP src tests kits game page_flipper ; -SubInclude HAIKU_TOP src tests kits game chart ; SubInclude HAIKU_TOP src tests kits game ParticlesII ; diff --git a/src/tests/kits/game/push_game_sound_test/Jamfile b/src/tests/kits/game/push_game_sound_test/Jamfile new file mode 100644 index 0000000000..81f11b616c --- /dev/null +++ b/src/tests/kits/game/push_game_sound_test/Jamfile @@ -0,0 +1,6 @@ +SubDir HAIKU_TOP src tests kits game push_game_sound_test ; + +SimpleTest push_game_sound_test + : push_game_sound_test.cpp + : game media be $(TARGET_LIBSUPC++) +; diff --git a/src/tests/kits/game/push_game_sound_test/push_game_sound_test.cpp b/src/tests/kits/game/push_game_sound_test/push_game_sound_test.cpp new file mode 100644 index 0000000000..820a9d485b --- /dev/null +++ b/src/tests/kits/game/push_game_sound_test/push_game_sound_test.cpp @@ -0,0 +1,189 @@ +/* + * Copyright 2009, Krzysztof Ćwiertnia (krzysiek.bmkx_gmail_com). + * All Rights Reserved. Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include + + +int +main(int argc, char *argv[]) +{ + // 256 frames * 4 buffer parts * 2 channels * 2 bytes per sample + // will give us internal buffer of 4096 bytes + size_t framesPerBufferPart = 256; + size_t bufferPartCount = 4; + + if (argc != 2 && argc != 4) { + printf("Usage: %s [ ]\n", + argv[0]); + return 0; + } + + if (argc == 4) { + size_t size = strtoul(argv[2], NULL, 10); + if (0 < size) + framesPerBufferPart = size; + size = strtoul(argv[3], NULL, 10); + if (size == 1) { + printf("at least 2 buffer parts are needed\n"); + return 0; + } + if (0 < size) + bufferPartCount = size; + } + + printf("frames per buffer part: %ld\n", framesPerBufferPart); + printf("buffer part count: %ld\n", bufferPartCount); + + BEntry entry(argv[1]); + if (entry.InitCheck() != B_OK || !entry.Exists()) { + printf("cannot open input file\n"); + return 0; + } + + entry_ref entryRef; + entry.GetRef(&entryRef); + + BMediaFile mediaFile(&entryRef); + if (mediaFile.InitCheck() != B_OK) { + printf("file not supported\n"); + return 0; + } + + if (mediaFile.CountTracks() == 0) { + printf("no tracks found in file\n"); + return 0; + } + + BMediaTrack *mediaTrack = mediaFile.TrackAt(0); + if (mediaTrack == NULL) { + printf("problem getting track from file\n"); + return 0; + } + + // propose format, let it decide frame rate, channels number and buf size + media_format format; + memset(&format, 0, sizeof(format)); + format.type = B_MEDIA_RAW_AUDIO; + format.u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT; + format.u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN; + + if (mediaTrack->DecodedFormat(&format) != B_OK) { + printf("cannot set decoder output format\n"); + return 0; + } + + printf("negotiated format:\n"); + printf("frame rate: %g Hz\n", format.u.raw_audio.frame_rate); + printf("channel count: %ld\n", format.u.raw_audio.channel_count); + printf("buffer size: %ld bytes\n", format.u.raw_audio.buffer_size); + + gs_audio_format gsFormat; + memset(&gsFormat, 0, sizeof(gsFormat)); + gsFormat.frame_rate = format.u.raw_audio.frame_rate; + gsFormat.channel_count = format.u.raw_audio.channel_count; + gsFormat.format = format.u.raw_audio.format; + gsFormat.byte_order = format.u.raw_audio.byte_order; + + BPushGameSound pushGameSound(framesPerBufferPart, &gsFormat, + bufferPartCount); + if (pushGameSound.InitCheck() != B_OK) { + printf("trouble initializing push game sound\n"); + } + + uint8 *buffer; + size_t bufferSize; + if (pushGameSound.LockForCyclic((void **)&buffer, &bufferSize) + != BPushGameSound::lock_ok) { + printf("cannot lock buffer\n"); + return 0; + } + memset(buffer, 0, bufferSize); + + if (pushGameSound.StartPlaying() != B_OK) { + printf("cannot start playback\n"); + return 0; + } + + printf("playing, press [esc] to exit...\n"); + + uint8 decoded[format.u.raw_audio.buffer_size * 2]; + size_t bufferPartSize = framesPerBufferPart + * format.u.raw_audio.channel_count + * (format.u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK); + size_t decodedSize = 0; + size_t partPos = 0; + size_t pos = pushGameSound.CurrentPosition(); + key_info keyInfo; + + while (true) { + // fill buffer part with data from decoded buffer + while (partPos < bufferPartSize && decodedSize) { + size_t size = min_c(bufferPartSize - partPos, decodedSize); + + memcpy(buffer + pos + partPos, decoded, size); + partPos += size; + + decodedSize -= size; + memmove(decoded, decoded + size, decodedSize); + } + + // if there are too little data to fill next buffer part + // read next decoded frames + if (partPos < bufferPartSize) { + int64 frameCount; + if (mediaTrack->ReadFrames(decoded + decodedSize, &frameCount) + != B_OK) + break; + if (frameCount == 0) + break; + + decodedSize += frameCount * format.u.raw_audio.channel_count + * (format.u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK); + + printf("\rtime: %.2f", (double) mediaTrack->CurrentTime() + / 1000000LL); + fflush(stdout); + continue; + } + + // this buffer part is done + partPos = 0; + pos += bufferPartSize; + if (bufferSize <= pos) + pos = 0; + + // playback sync + while (pushGameSound.CurrentPosition() == pos) + snooze(100); + + // check escape key state + if (get_key_info(&keyInfo) != B_OK) { + printf("\nkeyboard state read error\n"); + break; + } + if ((keyInfo.key_states[0] & 0x40) != 0) + break; + } + + pushGameSound.StopPlaying(); + + mediaFile.ReleaseTrack(mediaTrack); + mediaFile.CloseFile(); + + printf("\nfinished.\n"); + + return 0; +}