Added waveform functions
This commit is contained in:
		
							
								
								
									
										115
									
								
								src/waveform.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/waveform.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| #include "waveform.hpp" | ||||
|  | ||||
|  | ||||
| /* | ||||
| Given an input_buffer, create a waveform of size width, height. | ||||
|  | ||||
| @param input_buffer Buffer to read from. | ||||
| @param output Where to place output. Will be overwritten. | ||||
| @param width Width of waveform. This is how many values will be written to output. | ||||
| @param height Height of waveform. Every value in the output vector is less than or equal to height. | ||||
| */ | ||||
| void waveform_generate( | ||||
| 	const Buffer& input_buffer, | ||||
| 	std::vector<size_t>& output, | ||||
| 	size_t width, | ||||
| 	size_t height | ||||
| ) { | ||||
| 	const int samples_per_column = input_buffer.get_output().size() / width; | ||||
|  | ||||
| 	if (samples_per_column == 0) { | ||||
| 		printf("Too few samples %d\n", (int) input_buffer.get_output().size()); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	double bar_height; | ||||
| 	for (size_t x = 0; x < width; x++) { | ||||
| 		bar_height = 0; | ||||
|  | ||||
| 		// Average bins | ||||
| 		for (int j = 0; j < samples_per_column; j++) { | ||||
| 			bar_height += input_buffer.get_output()[x*samples_per_column+j] + INT16_MAX; | ||||
| 		} | ||||
| 		bar_height /= samples_per_column; | ||||
|  | ||||
| 		// Scale bar height | ||||
| 		bar_height *= height / (double) UINT16_MAX; | ||||
|  | ||||
| 		output[x] = (size_t) bar_height; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
| Draw a waveform in a bitmap. | ||||
|  | ||||
| @param waveform Waveform data, as generated by gen_waveform | ||||
| @param bitmap Bitmap to draw to. This will be modified, but will NOT be cleared. | ||||
| */ | ||||
| void waveform_draw_bitmap( | ||||
| 	const std::vector<size_t>& waveform, | ||||
| 	Bitmap& bitmap | ||||
| ) { | ||||
| 	size_t pt = 0; | ||||
| 	size_t prev_pt = 0; | ||||
| 	size_t delta; | ||||
| 	for (size_t x = 0; x < waveform.size(); x++) { | ||||
| 		prev_pt = pt; | ||||
| 		pt = waveform[x]; | ||||
|  | ||||
| 		bitmap.setpixel( | ||||
| 			pt, x, | ||||
| 			0xFF, 0x00, 0x00 | ||||
| 		); | ||||
|  | ||||
| 		// If the gap between two consecutive points is too big, | ||||
| 		// intermediate values are needed for the wave to be watchable. | ||||
| 		delta = pt>prev_pt ? pt-prev_pt : prev_pt-pt; | ||||
| 		if ( (x > 0) && (delta > 1) ){ | ||||
| 			const size_t half = (prev_pt + pt) / 2; | ||||
|  | ||||
| 			if (prev_pt < pt) { | ||||
| 				for (auto y = prev_pt; y < pt; y++) { | ||||
| 					bitmap.setpixel( | ||||
| 						y, x - (y < half), | ||||
| 						0xFF, 0x00, 0x00 | ||||
| 					); | ||||
| 				} | ||||
| 			} else { | ||||
| 				for (auto y = prev_pt; y > pt; y--) { | ||||
| 					bitmap.setpixel( | ||||
| 						y, x - (y > half), | ||||
| 						0xFF, 0x00, 0x00 | ||||
| 					); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
| Example: | ||||
|  | ||||
| int main(int argc, char *argv[]) { | ||||
| 	Buffer buf = Buffer( | ||||
| 		"/tmp/mpd.fifo", | ||||
| 		44100 / 2, // Keep 500ms of data in buffer | ||||
| 		(44100 / 60 * 10) | ||||
| 		// Double both if stereo | ||||
| 	); | ||||
|  | ||||
| 	Bitmap b = Bitmap(width, 100); | ||||
| 	std::vector<size_t> waveform; | ||||
| 	waveform.resize(width); | ||||
|  | ||||
| 	while(1) { | ||||
| 		b.clear(); | ||||
| 		buf.update(); | ||||
| 		waveform_generate(buf, waveform, width, 100); | ||||
| 		waveform_draw_bitmap(waveform, b); | ||||
| 		b.save("/tmp/o.bmp"); | ||||
| 	} | ||||
| } | ||||
| */ | ||||
							
								
								
									
										22
									
								
								src/waveform.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/waveform.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <cstdint> | ||||
| #include <vector> | ||||
|  | ||||
| #include "bitmap/bitmap.hpp" | ||||
| #include "buffer/buffer.hpp" | ||||
|  | ||||
|  | ||||
| void waveform_generate( | ||||
| 	const Buffer &input_buffer, | ||||
| 	std::vector<size_t>& output, | ||||
| 	size_t width, | ||||
| 	size_t height | ||||
| ); | ||||
|  | ||||
|  | ||||
| void waveform_draw_bitmap( | ||||
| 	const std::vector<size_t>& waveform, | ||||
| 	Bitmap& bitmap | ||||
| ); | ||||
		Reference in New Issue
	
	Block a user