Get an audio waveform image
| 157 | |
| 158 | // Get an audio waveform image |
| 159 | std::shared_ptr<QImage> Frame::GetWaveform(int width, int height, int Red, int Green, int Blue, int Alpha) |
| 160 | { |
| 161 | // Clear any existing waveform image |
| 162 | ClearWaveform(); |
| 163 | |
| 164 | // Init a list of lines |
| 165 | QVector<QPointF> lines; |
| 166 | QVector<QPointF> labels; |
| 167 | |
| 168 | // Calculate width of an image based on the # of samples |
| 169 | int total_samples = GetAudioSamplesCount(); |
| 170 | if (total_samples > 0) |
| 171 | { |
| 172 | // If samples are present... |
| 173 | int new_height = 200 * audio->getNumChannels(); |
| 174 | int height_padding = 20 * (audio->getNumChannels() - 1); |
| 175 | int total_height = new_height + height_padding; |
| 176 | int total_width = 0; |
| 177 | float zero_height = 1.0; // Used to clamp near-zero vales to this value to prevent gaps |
| 178 | |
| 179 | // Loop through each audio channel |
| 180 | float Y = 100.0; |
| 181 | for (int channel = 0; channel < audio->getNumChannels(); channel++) |
| 182 | { |
| 183 | float X = 0.0; |
| 184 | |
| 185 | // Get audio for this channel |
| 186 | const float *samples = audio->getReadPointer(channel); |
| 187 | |
| 188 | for (int sample = 0; sample < GetAudioSamplesCount(); sample++, X++) |
| 189 | { |
| 190 | // Sample value (scaled to -100 to 100) |
| 191 | float value = samples[sample] * 100.0; |
| 192 | |
| 193 | // Set threshold near zero (so we don't allow near-zero values) |
| 194 | // This prevents empty gaps from appearing in the waveform |
| 195 | if (value > -zero_height && value < 0.0) { |
| 196 | value = -zero_height; |
| 197 | } else if (value > 0.0 && value < zero_height) { |
| 198 | value = zero_height; |
| 199 | } |
| 200 | |
| 201 | // Append a line segment for each sample |
| 202 | lines.push_back(QPointF(X, Y)); |
| 203 | lines.push_back(QPointF(X, Y - value)); |
| 204 | } |
| 205 | |
| 206 | // Add Channel Label Coordinate |
| 207 | labels.push_back(QPointF(5.0, Y - 5.0)); |
| 208 | |
| 209 | // Increment Y |
| 210 | Y += (200 + height_padding); |
| 211 | total_width = X; |
| 212 | } |
| 213 | |
| 214 | // Create blank image |
| 215 | wave_image = std::make_shared<QImage>( |
| 216 | total_width, total_height, QImage::Format_RGBA8888_Premultiplied); |