bool SoundData::loadOgg(const std::string & filename) { clear(); short* samples; int channels; int sample_rate; int len; len = stb_vorbis_decode_filename(filename.c_str(), &channels, &sample_rate, &samples); if (!samples) { return false; } Uint32 dataSize = Uint32(len * channels * 2); if (!separateChannels((byte*)samples, dataSize, channels, 16)) { free(samples); return false; } free(samples); _channels = channels; _sampleRate = sample_rate; _bitsPerSample = 16; return true; }
// This is for OGG loading bool maxiSample::loadOgg(string fileName, int channel) { #ifdef VORBIS bool result; readChannel=channel; int channelx; // cout << fileName << endl; myDataSize = stb_vorbis_decode_filename(const_cast<char*>(fileName.c_str()), &channelx, &temp); result = myDataSize > 0; printf("\nchannels = %d\nlength = %d",channelx,myDataSize); printf("\n"); myChannels=(short)channelx; length=myDataSize; mySampleRate=44100; if (myChannels>1) { int position=0; int channel=readChannel; for (int i=channel;i<myDataSize*2;i+=myChannels) { temp[position]=temp[i]; position++; } } return result; // this should probably be something more descriptive #endif return 0; }
// stb_vorbis_decode_filename: decode an entire file to interleaved shorts void test_decode_filename(FILE *g, char *filename) { short *decoded; int channels, len; len = stb_vorbis_decode_filename(filename, &channels, &decoded); if (len) fwrite(decoded, 2, len*channels, g); else stb_fatal("Couldn't open {%s}", filename); }
VorbisFile::VorbisFile(const char *filename) { int channels; dataSize = stb_vorbis_decode_filename(filename, &channels, &sampleRate, reinterpret_cast<short**>(&data)); if (dataSize == -1) Log() << "Couldn't load OGG Vorbis file: " << filename << "\n"; if (channels > 1) format = AL_FORMAT_STEREO16; else format = AL_FORMAT_MONO16; }
static void loadSampleJob( void* data ) { if( data == NULL ) { llog( LOG_ERROR, "NULL data passed into loadSampleJob!" ); return; } ThreadedSoundLoadData* loadData = (ThreadedSoundLoadData*)data; // read the entire file into memory and decode it int channels; int rate; short* buffer; int numSamples = stb_vorbis_decode_filename( loadData->fileName, &channels, &rate, &buffer ); if( numSamples < 0 ) { llog( LOG_ERROR, "Error decoding sound sample %s", loadData->fileName ); goto error; } // convert it if( SDL_BuildAudioCVT( &( loadData->loadConverter ), AUDIO_S16, (Uint8)channels, rate, WORKING_FORMAT, loadData->desiredChannels, WORKING_RATE ) < 0 ) { llog( LOG_ERROR, "Unable to create converter for sound." ); goto error; } loadData->loadConverter.len = numSamples * channels * sizeof( buffer[0] ); size_t totLen = loadData->loadConverter.len * loadData->loadConverter.len_mult; if( loadData->loadConverter.len_mult > 1 ) { buffer = mem_Resize( buffer, loadData->loadConverter.len * loadData->loadConverter.len_mult ); // need to make sure there's enough room if( buffer == NULL ) { llog( LOG_ERROR, "Unable to allocate more memory for converting." ); goto error; } } loadData->loadConverter.buf = (Uint8*)buffer; SDL_ConvertAudio( &( loadData->loadConverter ) ); jq_AddMainThreadJob( bindSampleJob, (void*)loadData ); return; error: cleanUpThreadedSoundLoadData( loadData ); }
int snd_LoadSample( const char* fileName, Uint8 desiredChannels, bool loops ) { assert( ( desiredChannels >= 1 ) && ( desiredChannels <= 2 ) ); int newIdx = -1; for( int i = 0; ( i < ARRAY_SIZE( samples ) ) && ( newIdx < 0 ); ++i ) { if( samples[i].data == NULL ) { newIdx = i; } } if( newIdx < 0 ) { llog( LOG_ERROR, "Unable to find free space for sample." ); return -1; } // read the entire file into memory and decode it int channels; int rate; short* data; int numSamples = stb_vorbis_decode_filename( fileName, &channels, &rate, &data ); // convert it SDL_AudioCVT loadConverter; if( SDL_BuildAudioCVT( &loadConverter, AUDIO_S16, (Uint8)channels, rate, WORKING_FORMAT, desiredChannels, WORKING_RATE ) < 0 ) { llog( LOG_ERROR, "Unable to create converter for sound." ); newIdx = -1; goto clean_up; } loadConverter.len = numSamples * channels * sizeof( data[0] ); size_t totLen = loadConverter.len * loadConverter.len_mult; if( loadConverter.len_mult > 1 ) { data = mem_Resize( data, loadConverter.len * loadConverter.len_mult ); // need to make sure there's enough room if( data == NULL ) { llog( LOG_ERROR, "Unable to allocate more memory for converting." ); newIdx = -1; goto clean_up; } } loadConverter.buf = (Uint8*)data; if( SDL_ConvertAudio( &loadConverter ) < 0 ) { llog( LOG_ERROR, "Unable to convert sound: %s", SDL_GetError( ) ); newIdx = -1; goto clean_up; } // store it samples[newIdx].data = mem_Allocate( loadConverter.len_cvt ); memcpy( samples[newIdx].data, loadConverter.buf, loadConverter.len_cvt ); samples[newIdx].numChannels = desiredChannels; samples[newIdx].numSamples = loadConverter.len_cvt / ( desiredChannels * ( ( SDL_AUDIO_MASK_BITSIZE & WORKING_FORMAT ) / 8 ) ); samples[newIdx].loops = loops; clean_up: // clean up the working data mem_Release( data ); return newIdx; }
int main(int argc, char **argv) { int num_chan, samprate; int i, j, test, phase; short *output; if (argc == 1) { fprintf(stderr, "Usage: vorbseek {vorbisfile} [{vorbisfile]*]\n"); fprintf(stderr, "Tests various seek offsets to make sure they're sample exact.\n"); return 0; } #if 0 { // check that outofmem occurs correctly stb_vorbis_alloc va; va.alloc_buffer = malloc(1024*1024); for (i=0; i < 1024*1024; i += 10) { int error=0; stb_vorbis *v; va.alloc_buffer_length_in_bytes = i; v = stb_vorbis_open_filename(argv[1], &error, &va); if (v != NULL) break; printf("Error %d at %d\n", error, i); } } #endif for (j=1; j < argc; ++j) { unsigned int successes=0, attempts = 0; unsigned int num_samples = stb_vorbis_decode_filename(argv[j], &num_chan, &samprate, &output); break; if (num_samples == 0xffffffff) { fprintf(stderr, "Error: couldn't open file or not vorbis file: %s\n", argv[j]); goto fail; } if (num_chan != 2) { fprintf(stderr, "vorbseek testing only works with files with 2 channels, %s has %d\n", argv[j], num_chan); goto fail; } for (test=0; test < 5; ++test) { int error; stb_vorbis *v = stb_vorbis_open_filename(argv[j], &error, NULL); if (v == NULL) { fprintf(stderr, "Couldn't re-open %s for test #%d\n", argv[j], test); goto fail; } for (phase=0; phase < 3; ++phase) { unsigned int base = phase == 0 ? 0 : phase == 1 ? num_samples - test_count[test]*test_spacing[test] : num_samples/3; for (i=0; i < test_count[test]; ++i) { unsigned int pos = base + i*test_spacing[test]; if (pos > num_samples) // this also catches underflows continue; successes += try_seeking(v, pos, output, num_samples); attempts += 1; } } stb_vorbis_close(v); } printf("%d of %d seeks failed in %s (%d samples)\n", attempts-successes, attempts, argv[j], num_samples); free(output); } return 0; fail: return 1; }