TEST_F(WaveformGeneratorTest, shouldComputeMaxAndMinValuesFromStereoInput) { WaveformBuffer buffer; const int samples_per_pixel = 300; SamplesPerPixelScaleFactor scale_factor(samples_per_pixel); WaveformGenerator generator(buffer, scale_factor); const int sample_rate = 44100; const int channels = 2; const int BUFFER_SIZE = 1024; short samples[BUFFER_SIZE]; memset(samples, 0, sizeof(samples)); const int frames = BUFFER_SIZE / channels; bool result = generator.init(sample_rate, channels, BUFFER_SIZE); ASSERT_TRUE(result); ASSERT_TRUE(error.str().empty()); // even indexes: left channel, odd indexes: right channel samples[0] = 100; samples[1] = 102; samples[200] = 98; samples[201] = 100; samples[400] = -98; samples[401] = -100; samples[598] = -100; samples[599] = -102; samples[600] = 197; samples[601] = 199; samples[800] = -200; samples[801] = -202; samples[900] = -197; samples[901] = -199; samples[1022] = 200; samples[1023] = 202; result = generator.process(samples, frames); ASSERT_TRUE(result); generator.done(); // Check contents of buffer ASSERT_THAT(buffer.getSampleRate(), Eq(44100)); ASSERT_THAT(buffer.getSamplesPerPixel(), Eq(300)); ASSERT_THAT(buffer.getSize(), Eq(2)); // 512 / 300 = 1 remainder 212 // => 2 output points total // Check min and max values are average of left and right channels ASSERT_THAT(buffer.getMinSample(0), Eq(-101)); ASSERT_THAT(buffer.getMaxSample(0), Eq(101)); ASSERT_THAT(buffer.getMinSample(1), Eq(-201)); ASSERT_THAT(buffer.getMaxSample(1), Eq(201)); }
TEST_F(WaveformGeneratorTest, shouldComputeMaxAndMinValuesFromMonoInput) { WaveformBuffer buffer; const int samples_per_pixel = 300; SamplesPerPixelScaleFactor scale_factor(samples_per_pixel); WaveformGenerator generator(buffer, scale_factor); const int sample_rate = 44100; const int channels = 1; const int BUFFER_SIZE = 512; short samples[BUFFER_SIZE]; memset(samples, 0, sizeof(samples)); const int frames = BUFFER_SIZE / channels; bool result = generator.init(sample_rate, channels, BUFFER_SIZE); ASSERT_TRUE(result); ASSERT_TRUE(error.str().empty()); // samples for first waveform data point samples[0] = 100; samples[100] = 98; samples[200] = -98; samples[299] = -102; // samples for second waveform data point samples[300] = 197; samples[400] = -200; samples[450] = -197; samples[511] = 202; result = generator.process(samples, frames); ASSERT_TRUE(result); generator.done(); // Check contents of buffer ASSERT_THAT(buffer.getSampleRate(), Eq(44100)); ASSERT_THAT(buffer.getSamplesPerPixel(), Eq(300)); ASSERT_THAT(buffer.getSize(), Eq(2)); // 512 / 300 = 1 remainder 212 // => 2 output points total // Check min and max values ASSERT_THAT(buffer.getMinSample(0), Eq(-102)); ASSERT_THAT(buffer.getMaxSample(0), Eq(100)); ASSERT_THAT(buffer.getMinSample(1), Eq(-200)); ASSERT_THAT(buffer.getMaxSample(1), Eq(202)); }
TEST_F(WaveformGeneratorTest, shouldSetBufferAttributes) { WaveformBuffer buffer; const int samples_per_pixel = 300; WaveformGenerator generator(buffer, samples_per_pixel); const int sample_rate = 44100; const int channels = 2; const int BUFFER_SIZE = 1024; bool result = generator.init(sample_rate, channels, BUFFER_SIZE); ASSERT_TRUE(result); ASSERT_THAT(buffer.getSampleRate(), Eq(44100)); ASSERT_THAT(buffer.getSamplesPerPixel(), Eq(300)); }
TEST_F(WaveformGeneratorTest, shouldSucceedIfEndTimeGreaterThanStartTime) { WaveformBuffer buffer; DurationScaleFactor scale_factor(2.0, 3.0, 100); WaveformGenerator generator(buffer, scale_factor); const int sample_rate = 44100; const int channels = 2; const int BUFFER_SIZE = 1024; bool result = generator.init(sample_rate, channels, BUFFER_SIZE); ASSERT_TRUE(result); ASSERT_TRUE(error.str().empty()); ASSERT_THAT(generator.getSamplesPerPixel(), Eq(441)); ASSERT_THAT(buffer.getSampleRate(), Eq(44100)); ASSERT_THAT(buffer.getSamplesPerPixel(), Eq(441)); }
bool GdImageRenderer::create( const WaveformBuffer& buffer, const double start_time, const int image_width, const int image_height, const WaveformColors& colors, const bool render_axis_labels) { if (start_time < 0.0) { error_stream << "Invalid start time: minimum 0\n"; return false; } else if (start_time > MAX_START_TIME) { error_stream << "Invalid start time: maximum " << MAX_START_TIME << '\n'; return false; } if (image_width < 1) { error_stream << "Invalid image width: minimum 1\n"; return false; } if (image_height < 1) { error_stream << "Invalid image height: minimum 1\n"; return false; } const int sample_rate = buffer.getSampleRate(); if (sample_rate > MAX_SAMPLE_RATE) { error_stream << "Invalid sample rate: " << sample_rate << " Hz, maximum " << MAX_SAMPLE_RATE << " Hz\n"; return false; } const int samples_per_pixel = buffer.getSamplesPerPixel(); if (samples_per_pixel > MAX_ZOOM) { error_stream << "Invalid zoom: maximum " << MAX_ZOOM << '\n'; return false; } image_ = gdImageCreateTrueColor(image_width, image_height); if (image_ == nullptr) { error_stream << "Failed to create image\n"; return false; } assert(sample_rate != 0); assert(samples_per_pixel != 0); image_width_ = image_width; image_height_ = image_height; start_time_ = start_time; sample_rate_ = buffer.getSampleRate(); samples_per_pixel_ = samples_per_pixel; start_index_ = secondsToPixels(start_time); render_axis_labels_ = render_axis_labels; output_stream << "Image dimensions: " << image_width_ << "x" << image_height_ << " pixels" << "\nSample rate: " << sample_rate_ << " Hz" << "\nSamples per pixel: " << samples_per_pixel_ << "\nStart time: " << start_time_ << " seconds" << "\nStart index: " << start_index_ << "\nBuffer size: " << buffer.getSize() << "\nAxis labels: " << (render_axis_labels_ ? "yes" : "no") << std::endl; if (colors.hasAlpha()) { gdImageSaveAlpha(image_, 1); gdImageAlphaBlending(image_, 0); } initColors(colors); drawBackground(); if (render_axis_labels_) { drawBorder(); } drawWaveform(buffer); if (render_axis_labels_) { drawTimeAxisLabels(); } return true; }