Skip to content

Commit 0af0404

Browse files
committed
Fix CAF file output
1 parent 792592e commit 0af0404

2 files changed

Lines changed: 64 additions & 52 deletions

File tree

alc/backends/wave.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,9 @@ bool WaveBackend::reset()
380380
(isbformat ? SUBTYPE_BFORMAT_PCM.data() : SUBTYPE_PCM.data()), 1, 16, mFile.get());
381381

382382
fputs("data", mFile.get());
383-
fwrite32le(0xFFFFFFFF, mFile.get()); // 'data' header len; filled in at stop
383+
fwrite32le(~0u, mFile.get()); // 'data' header len; filled in at stop
384+
385+
mDataStart = ftell(mFile.get());
384386
}
385387
else
386388
{
@@ -452,14 +454,17 @@ bool WaveBackend::reset()
452454
/* Audio Data chunk */
453455
fputs("data", mFile.get());
454456
fwrite64be(~0_u64, mFile.get()); /* filled in at stop */
457+
458+
mDataStart = ftell(mFile.get());
459+
/* 32-bit uint, mEditCount */
460+
fwrite32be(0, mFile.get());
455461
}
456462

457463
if(ferror(mFile.get()))
458464
{
459465
ERR("Error writing header: {}", std::generic_category().message(errno));
460466
return false;
461467
}
462-
mDataStart = ftell(mFile.get());
463468

464469
setDefaultWFXChannelOrder();
465470

examples/allafplay.cpp

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -164,28 +164,28 @@ using ubyte = unsigned char;
164164
using ushort = unsigned short;
165165
using uint = unsigned int;
166166

167-
void fwrite16be(ushort val, std::filebuf &f)
167+
void fwrite16be(ushort val, std::ostream &f)
168168
{
169169
const auto data = std::array{static_cast<char>((val>>8)&0xff), static_cast<char>(val&0xff)};
170-
f.sputn(data.data(), std::ssize(data));
170+
f.write(data.data(), std::ssize(data));
171171
}
172172

173-
void fwrite32be(uint val, std::filebuf &f)
173+
void fwrite32be(uint val, std::ostream &f)
174174
{
175175
const auto data = std::array{static_cast<char>((val>>24)&0xff),
176176
static_cast<char>((val>>16)&0xff), static_cast<char>((val>>8)&0xff),
177177
static_cast<char>(val&0xff)};
178-
f.sputn(data.data(), std::ssize(data));
178+
f.write(data.data(), std::ssize(data));
179179
}
180180

181-
void fwrite64be(uint64_t val, std::filebuf &f)
181+
void fwrite64be(uint64_t val, std::ostream &f)
182182
{
183183
const auto data = std::array{static_cast<char>((val>>56)&0xff),
184184
static_cast<char>((val>>48)&0xff), static_cast<char>((val>>40)&0xff),
185185
static_cast<char>((val>>32)&0xff), static_cast<char>((val>>24)&0xff),
186186
static_cast<char>((val>>16)&0xff), static_cast<char>((val>>8)&0xff),
187187
static_cast<char>(val&0xff)};
188-
f.sputn(data.data(), std::ssize(data));
188+
f.write(data.data(), std::ssize(data));
189189
}
190190

191191

@@ -802,7 +802,7 @@ try {
802802
throw std::runtime_error{fmt::format("OpenAL error: {}", alGetString(err))};
803803
});
804804

805-
auto renderFile = std::filebuf{};
805+
auto renderFile = std::ofstream{};
806806
auto renderStart = int64_t{};
807807
auto leadIn = 0_z;
808808
auto leadOut = 0_z;
@@ -811,37 +811,40 @@ try {
811811
{
812812
auto *device = alcGetContextsDevice(alcGetCurrentContext());
813813

814-
auto chancount = uint{};
815-
switch(RenderChannels)
814+
const auto chancount = std::invoke([]() -> uint
816815
{
817-
case ALC_MONO_SOFT: chancount = 1; break;
818-
case ALC_STEREO_SOFT: chancount = 2; break;
819-
case ALC_QUAD_SOFT: chancount = 4; break;
820-
case ALC_SURROUND_5_1_SOFT: chancount = 6; break;
821-
case ALC_SURROUND_6_1_SOFT: chancount = 7; break;
822-
case ALC_SURROUND_7_1_SOFT: chancount = 8; break;
823-
case ALC_BFORMAT3D_SOFT:
824-
chancount = gsl::narrow<uint>((RenderAmbiOrder+1)*(RenderAmbiOrder+1));
825-
break;
826-
default:
827-
throw std::runtime_error{fmt::format("Unexpected channel enum: {:#x}",
828-
RenderChannels)};
829-
}
816+
switch(RenderChannels)
817+
{
818+
case ALC_MONO_SOFT: return 1u;
819+
case ALC_STEREO_SOFT: return 2u;
820+
case ALC_QUAD_SOFT: return 4u;
821+
case ALC_SURROUND_5_1_SOFT: return 6u;
822+
case ALC_SURROUND_6_1_SOFT: return 7u;
823+
case ALC_SURROUND_7_1_SOFT: return 8u;
824+
case ALC_BFORMAT3D_SOFT:
825+
return gsl::narrow<uint>((RenderAmbiOrder+1)*(RenderAmbiOrder+1));
826+
default:
827+
throw std::runtime_error{fmt::format("Unexpected channel enum: {:#x}",
828+
RenderChannels)};
829+
}
830+
});
830831

831-
auto samplesize = uint{};
832-
switch(RenderSamples)
832+
const auto samplesize = std::invoke([]() -> uint
833833
{
834-
case ALC_UNSIGNED_BYTE_SOFT: samplesize = 1; break;
835-
case ALC_BYTE_SOFT: samplesize = 1; break;
836-
case ALC_UNSIGNED_SHORT_SOFT: samplesize = 2; break;
837-
case ALC_SHORT_SOFT: samplesize = 2; break;
838-
case ALC_UNSIGNED_INT_SOFT: samplesize = 4; break;
839-
case ALC_INT_SOFT: samplesize = 4; break;
840-
case ALC_FLOAT_SOFT: samplesize = 4; break;
841-
default:
842-
throw std::runtime_error{fmt::format("Unexpected sample type enum: {:#x}",
843-
RenderSamples)};
844-
}
834+
switch(RenderSamples)
835+
{
836+
case ALC_UNSIGNED_BYTE_SOFT: return 1u;
837+
case ALC_BYTE_SOFT: return 1u;
838+
case ALC_UNSIGNED_SHORT_SOFT: return 2u;
839+
case ALC_SHORT_SOFT: return 2u;
840+
case ALC_UNSIGNED_INT_SOFT: return 4u;
841+
case ALC_INT_SOFT: return 4u;
842+
case ALC_FLOAT_SOFT: return 4u;
843+
default:
844+
throw std::runtime_error{fmt::format("Unexpected sample type enum: {:#x}",
845+
RenderSamples)};
846+
}
847+
});
845848
const auto framesize = size_t{chancount} * samplesize;
846849
renderbuf.resize(framesize * FramesPerPos);
847850

@@ -891,14 +894,14 @@ try {
891894
if(!renderFile.is_open())
892895
throw std::runtime_error{fmt::format("Failed to create {}", outname)};
893896

894-
renderFile.sputn("caff", 4);
897+
renderFile.write("caff", 4);
895898
fwrite16be(1, renderFile);
896899
fwrite16be(0, renderFile);
897900

898-
renderFile.sputn("desc", 4);
901+
renderFile.write("desc", 4);
899902
fwrite64be(32, renderFile);
900903
fwrite64be(std::bit_cast<uint64_t>(gsl::narrow_cast<double>(RenderSampleRate)),renderFile);
901-
renderFile.sputn("lpcm", 4);
904+
renderFile.write("lpcm", 4);
902905

903906
const auto flags = std::invoke([]
904907
{
@@ -947,16 +950,18 @@ try {
947950
});
948951
if(chanmask)
949952
{
950-
renderFile.sputn("chan", 4);
953+
renderFile.write("chan", 4);
951954
fwrite64be(12, renderFile);
952955
fwrite32be(0x10000, renderFile); /* kCAFChannelLayoutTag_UseChannelBitmap */
953956
fwrite32be(chanmask, renderFile);
954957
fwrite32be(0, renderFile);
955958
}
956959

957-
renderFile.sputn("data", 4);
960+
renderFile.write("data", 4);
958961
fwrite64be(~0_u64, renderFile); /* filled in at stop */
959-
renderStart = renderFile.pubseekoff(0, std::ios_base::cur);
962+
963+
renderStart = renderFile.tellp();
964+
fwrite32be(0, renderFile);
960965

961966
fmt::println("Rendering to {}...", outname);
962967
}
@@ -1037,12 +1042,12 @@ try {
10371042
leadIn -= std::ssize(renderbuf);
10381043
else if(leadIn > 0)
10391044
{
1040-
renderFile.sputn(std::to_address(renderbuf.begin()+leadIn),
1045+
renderFile.write(std::to_address(renderbuf.begin()+leadIn),
10411046
std::ssize(renderbuf)-leadIn);
10421047
leadIn = 0;
10431048
}
10441049
else
1045-
renderFile.sputn(renderbuf.data(), std::ssize(renderbuf));
1050+
renderFile.write(renderbuf.data(), std::ssize(renderbuf));
10461051
}
10471052
else
10481053
std::this_thread::sleep_for(std::chrono::milliseconds{10});
@@ -1152,12 +1157,12 @@ try {
11521157
leadIn -= std::ssize(renderbuf);
11531158
else if(leadIn > 0)
11541159
{
1155-
renderFile.sputn(std::to_address(renderbuf.begin()+leadIn),
1160+
renderFile.write(std::to_address(renderbuf.begin()+leadIn),
11561161
std::ssize(renderbuf)-leadIn);
11571162
leadIn = 0;
11581163
}
11591164
else
1160-
renderFile.sputn(renderbuf.data(), std::ssize(renderbuf));
1165+
renderFile.write(renderbuf.data(), std::ssize(renderbuf));
11611166
}
11621167
else
11631168
std::this_thread::sleep_for(std::chrono::milliseconds{10});
@@ -1170,20 +1175,22 @@ try {
11701175
alcRenderSamplesSOFT(alcGetContextsDevice(alcGetCurrentContext()),
11711176
renderbuf.data(), FramesPerPos);
11721177
const auto todo = std::min(std::ssize(renderbuf), leadOut);
1173-
renderFile.sputn(renderbuf.data(), todo);
1178+
renderFile.write(renderbuf.data(), todo);
11741179
leadOut -= todo;
11751180
}
11761181

11771182
if(renderStart > 0)
11781183
{
1179-
auto renderEnd = int64_t{renderFile.pubseekoff(0, std::ios_base::cur)};
1180-
if(renderEnd > 0)
1184+
auto renderEnd = int64_t{renderFile.tellp()};
1185+
if(renderEnd > renderStart)
11811186
{
11821187
const auto dataLen = renderEnd - renderStart;
1183-
if(renderFile.pubseekpos(renderStart-8) > 0)
1188+
if(renderFile.seekp(renderStart-8, std::ios_base::beg))
1189+
{
11841190
fwrite64be(gsl::narrow_cast<uint64_t>(dataLen), renderFile);
1191+
renderFile.seekp(0, std::ios_base::end);
1192+
}
11851193
}
1186-
renderFile.pubseekoff(0, std::ios_base::end);
11871194
}
11881195
}
11891196
catch(std::exception& e) {

0 commit comments

Comments
 (0)