64 ___INFOLOG(
"DiskWriterDriver thread started" );
70 soundInfo.channels = 2;
73 int sfformat = SF_FORMAT_WAV;
74 int bits = SF_FORMAT_PCM_16;
80 sfformat = SF_FORMAT_AIFF;
82#ifdef H2CORE_HAVE_FLAC_SUPPORT
84 sfformat = SF_FORMAT_FLAC;
88 sfformat = SF_FORMAT_WAV;
91 sfformat = SF_FORMAT_AU;
94 sfformat = SF_FORMAT_CAF;
97 sfformat = SF_FORMAT_W64;
99#ifdef H2CORE_HAVE_FLAC_SUPPORT
101 sfformat = SF_FORMAT_OGG;
102 bits = SF_FORMAT_VORBIS;
105#ifdef H2CORE_HAVE_OPUS_SUPPORT
107 sfformat = SF_FORMAT_OGG;
108 bits = SF_FORMAT_OPUS;
112 sfformat = SF_FORMAT_VOC;
114#ifdef H2CORE_HAVE_MP3_SUPPORT
116 sfformat = SF_FORMAT_MPEG;
117 bits = SF_FORMAT_MPEG_LAYER_III;
121 ___ERRORLOG( QString(
"Unsupported file extension [%1] using libsndfile [%2]" )
122 .arg( pDriver->
m_sFilename ).arg( sf_version_string() ) );
126 pthread_exit(
nullptr );
144 bits = SF_FORMAT_PCM_U8;
146 bits = SF_FORMAT_PCM_S8;
150 bits = SF_FORMAT_PCM_16;
153 bits = SF_FORMAT_PCM_24;
156 bits = SF_FORMAT_PCM_32;
160 soundInfo.format = sfformat|bits;
162 if ( !sf_format_check( &soundInfo ) ) {
163 ___ERRORLOG( QString(
"Error while checking format using libsndfile [%1]" )
164 .arg( sf_version_string() ) );
168 pthread_exit(
nullptr );
177 QString sPaddedPath = pDriver->
m_sFilename.append(
'\0' );
178 wchar_t* encodedFilename =
new wchar_t[ sPaddedPath.size() ];
180 sPaddedPath.toWCharArray( encodedFilename );
182 SNDFILE* pSndfile = sf_wchar_open( encodedFilename, SFM_WRITE,
184 delete encodedFilename;
186 SNDFILE* pSndfile = sf_open( pDriver->
m_sFilename.toLocal8Bit(), SFM_WRITE,
190 if ( pSndfile ==
nullptr ) {
191 ___ERRORLOG( QString(
"Unable to open file [%1] with format [%2] using libsndfile [%3]: %4" )
194 .arg( sf_version_string() )
195 .arg( sf_strerror( pSndfile ) ) );
199 pthread_exit(
nullptr );
204#ifdef H2CORE_HAVE_MP3_SUPPORT
206 int nBitrateMode = SF_BITRATE_MODE_VARIABLE;
207 if ( sf_command( pSndfile, SFC_SET_BITRATE_MODE, &nBitrateMode,
208 sizeof(
int) ) != SF_TRUE ) {
209 ___WARNINGLOG( QString(
"Unable to set variable bitrate for MP3 encoding: %1" )
210 .arg( sf_strerror( pSndfile ) ) );
215#ifdef H2CORE_HAVE_FLAC_SUPPORT
221 if ( sf_command( pSndfile, SFC_SET_COMPRESSION_LEVEL,
223 sizeof(
double) ) != SF_TRUE ) {
224 ___WARNINGLOG( QString(
"Unable to set compression level [%1]: %2" )
226 .arg( sf_strerror( pSndfile ) ) );
238 auto pSong = pHydrogen->
getSong();
242 pAudioEngine->play();
244 std::vector<PatternList*> *pPatternColumns = pSong->getPatternGroupVector();
245 int nColumns = pPatternColumns->size();
247 int nPatternSize, nBufferWriteLength;
250 int nMaxNumberOfSilentFrames = 200;
251 for (
int patternPosition = 0; patternPosition < nColumns; ++patternPosition ) {
253 PatternList *pColumn = ( *pPatternColumns )[ patternPosition ];
254 if ( pColumn->
size() != 0 ) {
262 pSong->getResolution() );
265 int nPatternLengthInFrames = fTicksize * nPatternSize;
266 int nFrameNumber = 0;
268 int nSuccessiveZeros = 0;
269 while ( ( patternPosition < nColumns - 1 &&
272 nFrameNumber < nPatternLengthInFrames ) ||
273 ( patternPosition == nColumns - 1 &&
276 ( nFrameNumber < nPatternLengthInFrames ||
277 pSampler->isRenderingNotes() ) ) ) {
286 if( patternPosition < nColumns - 1 &&
287 nPatternLengthInFrames - nFrameNumber < pDriver->m_nBufferSize ){
288 nLastRun = nPatternLengthInFrames - nFrameNumber;
289 nUsedBuffer = nLastRun;
299 if ( patternPosition == nColumns - 1 &&
300 nPatternLengthInFrames - nFrameNumber < nUsedBuffer ) {
315 nBufferWriteLength = 0;
317 int nSilentFrames = 0;
318 for (
int ii = 0; ii < nUsedBuffer; ++ii ) {
319 ++nBufferWriteLength;
321 if ( std::abs( pData_L[ii] ) == 0 &&
322 std::abs( pData_R[ii] ) == 0 ) {
326 if ( nSuccessiveZeros == nMaxNumberOfSilentFrames ) {
331 nBufferWriteLength = nUsedBuffer;
334 nFrameNumber += nBufferWriteLength;
336 for (
unsigned ii = 0; ii < nBufferWriteLength; ii++ ) {
337 if( pData_L[ ii ] > 1 ) {
339 }
else if( pData_L[ ii ] < -1 ) {
340 pData[ ii * 2 ] = -1;
342 pData[ ii * 2 ] = pData_L[ ii ];
345 if( pData_R[ ii ] > 1 ){
346 pData[ ii * 2 + 1 ] = 1;
347 }
else if ( pData_R[ ii ] < -1 ) {
348 pData[ ii * 2 + 1 ] = -1;
350 pData[ ii * 2 + 1 ] = pData_R[ ii ];
354 const int res = sf_writef_float( pSndfile, pData, nBufferWriteLength );
355 if ( res != (
int )nBufferWriteLength ) {
356 ___ERRORLOG( QString(
"Error during sf_write_float using [%1]. Floats written: [%2], target: [%3]. %4" )
357 .arg( sf_version_string() ).arg( res )
358 .arg( nBufferWriteLength )
359 .arg( sf_strerror(
nullptr ) ) );
366 if ( nSuccessiveZeros == nMaxNumberOfSilentFrames ) {
372 int nPercent =
static_cast<int>( ( float )(patternPosition +1) /
373 ( float )nColumns * 100.0 );
374 if ( nPercent < 100 ) {
387 sf_close( pSndfile );
391 pthread_exit(
nullptr );