Skip to content

Commit 4dd1982

Browse files
committed
fix: correct out of bounds and nullptr; format code
1 parent 64c7a34 commit 4dd1982

File tree

1 file changed

+122
-117
lines changed

1 file changed

+122
-117
lines changed

cpp/react-native-audio-analyzer.cpp

Lines changed: 122 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -10,129 +10,134 @@ extern "C" {
1010

1111
namespace audioanalyzer {
1212

13-
const char* FFmpegException::getMessage() const noexcept {
14-
return message;
15-
}
16-
17-
std::vector<AmplitudeData> analyzeAudio(const char *filename, FFmpegException *errorPtr) {
18-
std::vector<AmplitudeData> amplitudeData;
19-
20-
// Allocate memory for the AVFormatContext
21-
AVFormatContext *formatContext = avformat_alloc_context();
22-
if (!formatContext) {
23-
*errorPtr = FFmpegException("Failed to allocate AVFormatContext");
24-
return amplitudeData;
25-
}
26-
27-
// Open the input file
28-
if (avformat_open_input(&formatContext, filename, nullptr, nullptr) != 0) {
29-
avformat_free_context(formatContext);
30-
*errorPtr = FFmpegException("Failed to open input file");
31-
return amplitudeData;
32-
}
33-
34-
// Find stream information
35-
if (avformat_find_stream_info(formatContext, nullptr) < 0) {
36-
avformat_close_input(&formatContext);
37-
*errorPtr = FFmpegException("Failed to find stream information");
38-
return amplitudeData;
39-
}
40-
41-
// Find the best audio stream
42-
int audioStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
43-
if (audioStreamIndex < 0) {
44-
avformat_close_input(&formatContext);
45-
*errorPtr = FFmpegException("Failed to find audio stream");
46-
return amplitudeData;
47-
}
48-
49-
// Get codec parameters and find the corresponding decoder
50-
AVCodecParameters *codecParameters = formatContext->streams[audioStreamIndex]->codecpar;
51-
const AVCodec *codec = avcodec_find_decoder(codecParameters->codec_id);
52-
if (!codec) {
53-
avformat_close_input(&formatContext);
54-
*errorPtr = FFmpegException("Failed to find codec");
55-
return amplitudeData;
56-
}
57-
58-
// Allocate memory for the AVCodecContext
59-
AVCodecContext *codecContext = avcodec_alloc_context3(codec);
60-
if (!codecContext) {
61-
avformat_close_input(&formatContext);
62-
*errorPtr = FFmpegException("Failed to allocate AVCodecContext");
63-
return amplitudeData;
64-
}
65-
66-
// Set codec parameters
67-
if (avcodec_parameters_to_context(codecContext, codecParameters) < 0) {
68-
avformat_close_input(&formatContext);
69-
avcodec_free_context(&codecContext);
70-
*errorPtr = FFmpegException("Failed to set codec parameters");
71-
return amplitudeData;
72-
}
73-
74-
// Open the codec
75-
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
76-
avformat_close_input(&formatContext);
77-
avcodec_free_context(&codecContext);
78-
*errorPtr = FFmpegException("Failed to open codec");
79-
return amplitudeData;
80-
}
81-
82-
// Allocate memory for AVPacket and AVFrame
83-
AVPacket packet;
84-
AVFrame *frame = av_frame_alloc();
85-
86-
// Initialize variables for audio analysis
87-
int sampleRate = codecContext->sample_rate;
88-
double accumulatedAmplitude = 0.0;
89-
long sampleCount = 0;
90-
91-
// Read frames from the input file
92-
while (av_read_frame(formatContext, &packet) >= 0) {
93-
if (packet.stream_index == audioStreamIndex) {
94-
// Send the packet to the codec
95-
if (avcodec_send_packet(codecContext, &packet) < 0) {
96-
break;
97-
}
98-
99-
// Receive frames from the codec
100-
while (avcodec_receive_frame(codecContext, frame) >= 0) {
101-
double timestampInSeconds = frame->pts * av_q2d(formatContext->streams[audioStreamIndex]->time_base);
102-
103-
// Calculate amplitude for each sample in the frame
104-
for (int i = 0; i < frame->nb_samples; i++) {
105-
for (int ch = 0; ch < codecContext->channels; ch++) {
106-
accumulatedAmplitude += std::abs(frame->data[ch][i]);
107-
sampleCount++;
108-
109-
// Calculate amplitude per second and store the data
110-
if (sampleCount >= sampleRate) {
111-
double amplitudePerSecond = accumulatedAmplitude / sampleRate;
112-
113-
AmplitudeData data{};
114-
data.timeInSeconds = timestampInSeconds;
115-
data.amplitude = amplitudePerSecond;
116-
117-
amplitudeData.push_back(data);
13+
const char* FFmpegException::getMessage() const noexcept {
14+
return message;
15+
}
11816

119-
accumulatedAmplitude = 0.0;
120-
sampleCount = 0;
17+
std::vector<AmplitudeData> analyzeAudio(const char *filename, FFmpegException *errorPtr) {
18+
std::vector<AmplitudeData> amplitudeData;
19+
20+
// Allocate memory for the AVFormatContext
21+
AVFormatContext *formatContext = avformat_alloc_context();
22+
if (!formatContext) {
23+
*errorPtr = FFmpegException("Failed to allocate AVFormatContext");
24+
return amplitudeData;
25+
}
26+
27+
// Open the input file
28+
if (avformat_open_input(&formatContext, filename, nullptr, nullptr) != 0) {
29+
avformat_free_context(formatContext);
30+
*errorPtr = FFmpegException("Failed to open input file");
31+
return amplitudeData;
32+
}
33+
34+
// Find stream information
35+
if (avformat_find_stream_info(formatContext, nullptr) < 0) {
36+
avformat_close_input(&formatContext);
37+
*errorPtr = FFmpegException("Failed to find stream information");
38+
return amplitudeData;
39+
}
40+
41+
// Find the best audio stream
42+
int audioStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
43+
if (audioStreamIndex < 0) {
44+
avformat_close_input(&formatContext);
45+
*errorPtr = FFmpegException("Failed to find audio stream");
46+
return amplitudeData;
47+
}
48+
49+
// Get codec parameters and find the corresponding decoder
50+
AVCodecParameters *codecParameters = formatContext->streams[audioStreamIndex]->codecpar;
51+
const AVCodec *codec = avcodec_find_decoder(codecParameters->codec_id);
52+
if (!codec) {
53+
avformat_close_input(&formatContext);
54+
*errorPtr = FFmpegException("Failed to find codec");
55+
return amplitudeData;
56+
}
57+
58+
// Allocate memory for the AVCodecContext
59+
AVCodecContext *codecContext = avcodec_alloc_context3(codec);
60+
if (!codecContext) {
61+
avformat_close_input(&formatContext);
62+
*errorPtr = FFmpegException("Failed to allocate AVCodecContext");
63+
return amplitudeData;
64+
}
65+
66+
// Set codec parameters
67+
if (avcodec_parameters_to_context(codecContext, codecParameters) < 0) {
68+
avformat_close_input(&formatContext);
69+
avcodec_free_context(&codecContext);
70+
*errorPtr = FFmpegException("Failed to set codec parameters");
71+
return amplitudeData;
72+
}
73+
74+
// Open the codec
75+
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
76+
avformat_close_input(&formatContext);
77+
avcodec_free_context(&codecContext);
78+
*errorPtr = FFmpegException("Failed to open codec");
79+
return amplitudeData;
80+
}
81+
82+
// Allocate memory for AVPacket and AVFrame
83+
AVPacket packet;
84+
AVFrame *frame = av_frame_alloc();
85+
86+
// Initialize variables for audio analysis
87+
int sampleRate = codecContext->sample_rate;
88+
double accumulatedAmplitude = 0.0;
89+
long sampleCount = 0;
90+
91+
// Read frames from the input file
92+
while (av_read_frame(formatContext, &packet) >= 0) {
93+
if (packet.stream_index == audioStreamIndex) {
94+
// Send the packet to the codec
95+
if (avcodec_send_packet(codecContext, &packet) < 0) {
96+
break;
97+
}
98+
99+
// Receive frames from the codec
100+
while (avcodec_receive_frame(codecContext, frame) >= 0) {
101+
double timestampInSeconds = frame->pts * av_q2d(formatContext->streams[audioStreamIndex]->time_base);
102+
103+
// Calculate amplitude for each sample in the frame
104+
for (int i = 0; i < frame->nb_samples; i++) {
105+
for (int ch = 0; ch < codecContext->ch_layout.nb_channels; ch++) {
106+
if (frame->data[ch]) {
107+
// Check if the index is within bounds
108+
if (i < frame->linesize[ch]) {
109+
accumulatedAmplitude += frame->data[ch][i];
110+
sampleCount++;
111+
112+
// Calculate amplitude per second and store the data
113+
if (sampleCount >= sampleRate) {
114+
double amplitudePerSecond = accumulatedAmplitude / sampleRate;
115+
116+
AmplitudeData data{};
117+
data.timeInSeconds = timestampInSeconds;
118+
data.amplitude = amplitudePerSecond;
119+
120+
amplitudeData.push_back(data);
121+
122+
accumulatedAmplitude = 0.0;
123+
sampleCount = 0;
124+
}
121125
}
122126
}
123127
}
124128
}
125129
}
126-
127-
// Release the packet
128-
av_packet_unref(&packet);
129130
}
130-
131-
// Clean up resources
132-
avformat_close_input(&formatContext);
133-
avcodec_free_context(&codecContext);
134-
av_frame_free(&frame);
135-
136-
return amplitudeData;
131+
132+
// Release the packet
133+
av_packet_unref(&packet);
137134
}
135+
136+
// Clean up resources
137+
avformat_close_input(&formatContext);
138+
avcodec_free_context(&codecContext);
139+
av_frame_free(&frame);
140+
141+
return amplitudeData;
142+
}
138143
}

0 commit comments

Comments
 (0)