From 0aaf5eb1ae99f9b0b78aa678191fde335f1fbc4e Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Sun, 7 May 2006 20:25:45 +0000 Subject: [PATCH] added a sound output class to push data to the mixer, also started audio and video play threads git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17357 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/mediaplayer/Controller.cpp | 28 +++++++ src/apps/mediaplayer/Controller.h | 7 ++ src/apps/mediaplayer/Jamfile | 1 + src/apps/mediaplayer/SoundOutput.cpp | 120 +++++++++++++++++++++++++++ src/apps/mediaplayer/SoundOutput.h | 55 ++++++++++++ 5 files changed, 211 insertions(+) create mode 100644 src/apps/mediaplayer/SoundOutput.cpp create mode 100644 src/apps/mediaplayer/SoundOutput.h diff --git a/src/apps/mediaplayer/Controller.cpp b/src/apps/mediaplayer/Controller.cpp index a50627cfa3..a4419f964a 100644 --- a/src/apps/mediaplayer/Controller.cpp +++ b/src/apps/mediaplayer/Controller.cpp @@ -300,3 +300,31 @@ Controller::IsPaused() { return fPaused; } + + +int32 +Controller::audio_play_thread(void *self) +{ + static_cast(self)->AudioPlayThread(); + return 0; +} + + +int32 +Controller::video_play_thread(void *self) +{ + static_cast(self)->VideoPlayThread(); + return 0; +} + + +void +Controller::AudioPlayThread() +{ +} + + +void +Controller::VideoPlayThread() +{ +} diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index b0c2ee03bd..c5680f8088 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -62,6 +62,11 @@ public: void VolumeDown(); private: + static int32 audio_play_thread(void *self); + static int32 video_play_thread(void *self); + + void AudioPlayThread(); + void VideoPlayThread(); private: VideoView * fVideoView; @@ -78,6 +83,8 @@ private: media_format fVideoFormat; sem_id fAudioPlaySem; sem_id fVideoPlaySem; + thread_id fAudioPlayThread; + thread_id fVideoPlayThread; }; diff --git a/src/apps/mediaplayer/Jamfile b/src/apps/mediaplayer/Jamfile index 9858dace0f..b837c688c5 100644 --- a/src/apps/mediaplayer/Jamfile +++ b/src/apps/mediaplayer/Jamfile @@ -11,6 +11,7 @@ Application MediaPlayer : MainApp.cpp MainWin.cpp Playlist.cpp + SoundOutput.cpp TransportButton.cpp TransportControlGroup.cpp VideoNode.cpp diff --git a/src/apps/mediaplayer/SoundOutput.cpp b/src/apps/mediaplayer/SoundOutput.cpp new file mode 100644 index 0000000000..f158bf6d31 --- /dev/null +++ b/src/apps/mediaplayer/SoundOutput.cpp @@ -0,0 +1,120 @@ +/* + * SoundOutput.cpp - Media Player for the Haiku Operating System + * + * Copyright (C) 2006 Marcus Overhagen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include +#include +#include +#include + +#include "SoundOutput.h" + +SoundOutput::SoundOutput(const char *name, const media_multi_audio_format &format) + : fSoundPlayer(new(nothrow) BSoundPlayer(static_cast(&format), name, play_buffer, NULL, this)) + , fBuffer(new(nothrow) uint8[format.buffer_size]) + , fBufferSize(format.buffer_size) + , fBufferWriteable(create_sem(1, "SoundOutput writeable")) + , fBufferReadable(create_sem(0, "SoundOutput readable")) + , fBufferDuration(0) + , fIsPlaying(false) +{ + if (format.channel_count > 0 && format.frame_rate > 0 && (format.format & 0xf) != 0) + fBufferDuration = bigtime_t(1000000.0 * (format.buffer_size / (format.channel_count * (format.format & 0xf))) / format.frame_rate); + printf("SoundOutput: buffer duration is %Ld\n", fBufferDuration); +} + + +SoundOutput::~SoundOutput() +{ + delete fSoundPlayer; + delete_sem(fBufferWriteable); + delete_sem(fBufferReadable); + delete [] fBuffer; +} + + +status_t +SoundOutput::InitCheck() +{ + if (!fSoundPlayer || !fBuffer || fBufferSize <= 0 || fBufferWriteable < B_OK || fBufferReadable < B_OK) + return B_ERROR; + return fSoundPlayer->InitCheck(); +} + + +bigtime_t +SoundOutput::Latency() +{ + return fSoundPlayer->Latency() + fBufferDuration; +} + + +float +SoundOutput::Volume() +{ + return fSoundPlayer->Volume(); +} + + +void +SoundOutput::SetVolume(float new_volume) +{ + fSoundPlayer->SetVolume(new_volume); +} + + +void +SoundOutput::Play(const void *data, size_t size) +{ + ASSERT(size > 0 && size <= fBufferSize); + acquire_sem(fBufferWriteable); + memcpy(fBuffer, data, size); + size_t fillsize = fBufferSize - size; + if (fillsize) + memset(fBuffer + size, 0, fillsize); + release_sem(fBufferReadable); + if (!fIsPlaying) { + fSoundPlayer->SetHasData(true); + fSoundPlayer->Start(); + fIsPlaying = true; + } +} + + +void +SoundOutput::PlayBuffer(void *buffer) +{ + if (acquire_sem_etc(fBufferReadable, 1, B_RELATIVE_TIMEOUT, fBufferDuration) != B_OK) { + printf("SoundOutput: buffer not ready, playing silence\n"); + memset(buffer, 0, fBufferSize); + return; + } + memcpy(buffer, fBuffer, fBufferSize); + release_sem(fBufferWriteable); +} + + +void +SoundOutput::play_buffer(void *cookie, void *buffer, size_t size, const media_raw_audio_format & format) +{ + ASSERT(size == static_cast(cookie)->fBufferSize); + ASSERT(size == format.buffer_size); + static_cast(cookie)->PlayBuffer(buffer); +} + diff --git a/src/apps/mediaplayer/SoundOutput.h b/src/apps/mediaplayer/SoundOutput.h new file mode 100644 index 0000000000..a17b528305 --- /dev/null +++ b/src/apps/mediaplayer/SoundOutput.h @@ -0,0 +1,55 @@ +/* + * SoundOutput.h - Media Player for the Haiku Operating System + * + * Copyright (C) 2006 Marcus Overhagen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef __SOUND_OUTPUT_H +#define __SOUND_OUTPUT_H + +#include + + +class SoundOutput +{ +public: + SoundOutput(const char *name, const media_multi_audio_format &format); + ~SoundOutput(); + + status_t InitCheck(); + + bigtime_t Latency(); + + float Volume(); + void SetVolume(float new_volume); + + void Play(const void *data, size_t size); + +private: + static void play_buffer(void *cookie, void *buffer, size_t size, const media_raw_audio_format & format); + void PlayBuffer(void *buffer); + +private: + BSoundPlayer * fSoundPlayer; + uint8 * fBuffer; + size_t fBufferSize; + sem_id fBufferWriteable; + sem_id fBufferReadable; + bigtime_t fBufferDuration; + bool fIsPlaying; +}; + +#endif