SDL_mixer now playing video stream audio!

This commit is contained in:
Scott Duensing 2019-11-24 19:25:48 -06:00
parent 1f43bfc742
commit 06632fbcd7
5 changed files with 29 additions and 54 deletions

View file

@ -53,9 +53,10 @@
#define true 1
#define false 0
#define AUDIO_RING_SIZE 4096
#define AUDIO_RING_SIZE (64 * 1024)
#define AUDIO_SAMPLES (AUDIO_RING_SIZE / (16 /* average bytes per sample */ * 2 /* channels */))
#define AUDIO_SILENCE_SECONDS 4
#define AUDIO_SILENCE_SECONDS 2
#define AUDIO_CHUNK_MULTIPLIER 2
typedef struct AudioRingBufferS {
@ -77,17 +78,13 @@ void dequeueVideoAudio(int channel, void *stream, int len, void *udata) {
(void)channel;
ring->sizeTemp = ringbuf_bytes_used(ring->ring);
ring->sizeTemp = ringbuf_bytes_used(ring->ring); // We do this in case more space is used by the mixer while we're working on this
if (len > (int)ring->sizeTemp) {
toCopy = (int)ring->sizeTemp;
}
if (SDL_LockMutex(ring->mutex) == 0) {
if (SDL_LockMutex(ring->mutex) < 0) die("Unable to lock mutex for ringbuf_memcpy_from");
ringbuf_memcpy_from(stream, ring->ring, (size_t)toCopy);
SDL_UnlockMutex(ring->mutex);
} else {
die("Unable to lock mutex for ringbuf_memcpy_from");
}
if (SDL_UnlockMutex(ring->mutex) < 0) die("Unable to unlock mutex for ringbuf_memcpy_from");
//say("Dequeued %d bytes of audio data. Buffer is now %d.", toCopy, ringbuf_bytes_used(ring->ring));
}
@ -294,28 +291,35 @@ int main(int argc, char *argv[]) {
break;
}
if (audioProps->Channels > 2) die("Only mono and stereo audio are supported.");
// Create audio mixer device
err = Mix_OpenAudioDevice(44100, audioFormat, 2, audioSampleSize * audioProps->Channels, NULL, 0);
err = Mix_OpenAudio(audioProps->SampleRate, audioFormat, 2, audioSampleSize * audioProps->Channels * AUDIO_CHUNK_MULTIPLIER);
if (err != 0) die("%s", Mix_GetError());
// Create a buffer for reading audio from the video stream
audioSampleSize = audioSampleBytes * audioProps->Channels;
audioBuffer = (byte *)malloc((size_t)(audioSampleSize * AUDIO_SAMPLES) * sizeof(byte));
if (!audioBuffer) die("Unable to allocate %ld byte audio buffer.", ((size_t)(audioSampleSize * AUDIO_SAMPLES) * sizeof(byte)));
// Create a ring buffer to pass audio data from the video to the mixer
audioRingBuffer.ring = ringbuf_new(AUDIO_RING_SIZE);
if (!audioRingBuffer.ring) die("Unable to allocate %ld audio ring buffer.", AUDIO_RING_SIZE);
audioRingBuffer.mutex = SDL_CreateMutex();
if (!audioRingBuffer.mutex) die("Unable to create audio ring buffer mutex.");
// Create a block of silent audio to overlay with video stream audio
audioSilenceSize = (Uint32)audioSampleSize * (Uint32)audioProps->SampleRate * AUDIO_SILENCE_SECONDS;
audioSilenceRaw = (byte *)calloc(1, (size_t)audioSilenceSize * sizeof(byte));
if (!audioSilenceRaw) die("Unable to allocate %ld silence buffer.", audioSilenceSize);
// Load silent audio
silenceChunk = Mix_QuickLoad_RAW(audioSilenceRaw, audioSilenceSize);
if (!silenceChunk) die("%s", Mix_GetError());
// Start silent audio playback & immediately pause it
audioSilenceChannel = Mix_PlayChannel(-1, silenceChunk, -1);
if (audioSilenceChannel < 0) die("%s", Mix_GetError());
// Register effect to provide video stream audio on this channel
Mix_RegisterEffect(audioSilenceChannel, dequeueVideoAudio, NULL, &audioRingBuffer);
@ -404,12 +408,9 @@ int main(int argc, char *argv[]) {
}
if (resetTime) {
if (SDL_LockMutex(audioRingBuffer.mutex) == 0) {
if (SDL_LockMutex(audioRingBuffer.mutex) < 0) die("Unable to lock mutex for ringbuf_reset");
ringbuf_reset(audioRingBuffer.ring);
SDL_UnlockMutex(audioRingBuffer.mutex);
} else {
die("Unable to lock mutex for ringbuf_reset");
}
if (SDL_UnlockMutex(audioRingBuffer.mutex) < 0) die("Unable to unlock mutex for ringbuf_reset");
lastTickTime = 0;
frameDeltaTime = 0;
audioPosition = (int64_t)((double)(timestamp * 0.001) * (double)audioProps->SampleRate);
@ -433,12 +434,9 @@ int main(int argc, char *argv[]) {
// Are we reading anything?
if (audioCount > 0) {
if (FFMS_GetAudio(audioSource, audioBuffer, audioPosition, audioCount, &errInfo)) die("%s", errInfo.Buffer);
if (SDL_LockMutex(audioRingBuffer.mutex) == 0) {
if (SDL_LockMutex(audioRingBuffer.mutex) < 0) die("Unable to lock mutex for ringbuf_memcpy_into");
ringbuf_memcpy_into(audioRingBuffer.ring, audioBuffer, (size_t)(audioCount * audioSampleSize));
SDL_UnlockMutex(audioRingBuffer.mutex);
} else {
die("Unable to lock mutex for ringbuf_memcpy_into");
}
if (SDL_UnlockMutex(audioRingBuffer.mutex) < 0) die("Unable to unlock mutex for ringbuf_memcpy_into");
//say("Added %d samples (%d bytes) to ring buffer. Buffer is now %d bytes", audioCount, audioCount * audioSampleSize, ringbuf_bytes_used(audioRingBuffer.ring));
audioPosition += audioCount;
}

0
singe/postLink.sh Normal file → Executable file
View file

View file

@ -22,7 +22,7 @@
if [[ -z $1 ]]; then
BITS=64
THIRDPARTY=$(pwd)
DEST="${THIRDPARTY}/../../thirdparty-build/${BITS}"
DEST="${THIRDPARTY}/../thirdparty-build/${BITS}"
else
THIRDPARTY=$1
DEST=$2/$3

View file

@ -63,9 +63,10 @@ CONFIG += bits64
BUILDTHIRDARGS = \"$$PWD/thirdparty\" \"$$OUT_PWD/../thirdparty-build\" $$BITNESS
win32 {
BUILDTHIRD.commands = cmd.exe /c $$PWD\\thirdparty\\build.bat $$BUILDTHIRDARGS
# Placeholder - doesn't work
BUILDTHIRD.commands = cmd.exe /c $$PWD\\preBuild.bat $$BUILDTHIRDARGS
} else {
BUILDTHIRD.commands = bash $$PWD/thirdparty/build.sh $$BUILDTHIRDARGS
BUILDTHIRD.commands = bash $$PWD/preBuild.sh $$BUILDTHIRDARGS
}
BUILDTHIRD.target = this
PRE_TARGETDEPS += this
@ -137,8 +138,7 @@ LIBS += \
-ldl
OTHER_FILES += \
thirdparty/build.sh \
thirdparty/build.bat \
preBuild.sh \
postLink.sh
# Strip & UPX the final result

View file

@ -1,23 +0,0 @@
@echo off
goto skipLicense
#
# Singe 2
# Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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.
#
:skipLicense