OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <array> | 11 #include <array> |
12 #include <memory> | 12 #include <memory> |
| 13 #include <utility> |
13 | 14 |
14 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
15 #include "webrtc/base/fakeclock.h" | 16 #include "webrtc/base/fakeclock.h" |
16 #include "webrtc/common_audio/mocks/mock_smoothing_filter.h" | 17 #include "webrtc/common_audio/mocks/mock_smoothing_filter.h" |
17 #include "webrtc/common_types.h" | 18 #include "webrtc/common_types.h" |
18 #include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_audio_netw
ork_adaptor.h" | 19 #include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_audio_netw
ork_adaptor.h" |
19 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" | 20 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" |
20 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" | 21 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" |
21 #include "webrtc/test/field_trial.h" | 22 #include "webrtc/test/field_trial.h" |
22 #include "webrtc/test/gmock.h" | 23 #include "webrtc/test/gmock.h" |
(...skipping 15 matching lines...) Expand all Loading... |
38 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 39 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); |
39 config.num_channels = codec_inst.channels; | 40 config.num_channels = codec_inst.channels; |
40 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); | 41 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); |
41 config.payload_type = codec_inst.pltype; | 42 config.payload_type = codec_inst.pltype; |
42 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 43 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip |
43 : AudioEncoderOpus::kAudio; | 44 : AudioEncoderOpus::kAudio; |
44 config.supported_frame_lengths_ms.push_back(config.frame_size_ms); | 45 config.supported_frame_lengths_ms.push_back(config.frame_size_ms); |
45 return config; | 46 return config; |
46 } | 47 } |
47 | 48 |
| 49 AudioEncoderOpus::Config CreateConfigWithParameters( |
| 50 const SdpAudioFormat::Parameters& params) { |
| 51 SdpAudioFormat format("opus", 48000, 2, params); |
| 52 return AudioEncoderOpus::CreateConfig(0, format); |
| 53 } |
| 54 |
48 struct AudioEncoderOpusStates { | 55 struct AudioEncoderOpusStates { |
49 std::shared_ptr<MockAudioNetworkAdaptor*> mock_audio_network_adaptor; | 56 std::shared_ptr<MockAudioNetworkAdaptor*> mock_audio_network_adaptor; |
50 MockSmoothingFilter* mock_bitrate_smoother; | 57 MockSmoothingFilter* mock_bitrate_smoother; |
51 std::unique_ptr<AudioEncoderOpus> encoder; | 58 std::unique_ptr<AudioEncoderOpus> encoder; |
52 std::unique_ptr<SimulatedClock> simulated_clock; | 59 std::unique_ptr<SimulatedClock> simulated_clock; |
53 AudioEncoderOpus::Config config; | 60 AudioEncoderOpus::Config config; |
54 }; | 61 }; |
55 | 62 |
56 AudioEncoderOpusStates CreateCodec(size_t num_channels) { | 63 AudioEncoderOpusStates CreateCodec(size_t num_channels) { |
57 AudioEncoderOpusStates states; | 64 AudioEncoderOpusStates states; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 config.enable_dtx = rtc::Optional<bool>(kEnableDtx); | 108 config.enable_dtx = rtc::Optional<bool>(kEnableDtx); |
102 config.num_channels = rtc::Optional<size_t>(kNumChannels); | 109 config.num_channels = rtc::Optional<size_t>(kNumChannels); |
103 config.uplink_packet_loss_fraction = | 110 config.uplink_packet_loss_fraction = |
104 rtc::Optional<float>(kPacketLossFraction); | 111 rtc::Optional<float>(kPacketLossFraction); |
105 return config; | 112 return config; |
106 } | 113 } |
107 | 114 |
108 void CheckEncoderRuntimeConfig( | 115 void CheckEncoderRuntimeConfig( |
109 const AudioEncoderOpus* encoder, | 116 const AudioEncoderOpus* encoder, |
110 const AudioNetworkAdaptor::EncoderRuntimeConfig& config) { | 117 const AudioNetworkAdaptor::EncoderRuntimeConfig& config) { |
111 EXPECT_EQ(*config.bitrate_bps, encoder->GetTargetBitrate()); | 118 EXPECT_EQ(config.bitrate_bps, encoder->GetTargetBitrate()); |
112 EXPECT_EQ(*config.frame_length_ms, encoder->next_frame_length_ms()); | 119 EXPECT_EQ(config.frame_length_ms, encoder->next_frame_length_ms()); |
113 EXPECT_EQ(*config.enable_fec, encoder->fec_enabled()); | 120 EXPECT_EQ(config.enable_fec, encoder->fec_enabled()); |
114 EXPECT_EQ(*config.enable_dtx, encoder->GetDtx()); | 121 EXPECT_EQ(config.enable_dtx, encoder->GetDtx()); |
115 EXPECT_EQ(*config.num_channels, encoder->num_channels_to_encode()); | 122 EXPECT_EQ(config.num_channels, encoder->num_channels_to_encode()); |
116 } | 123 } |
117 | 124 |
118 // Create 10ms audio data blocks for a total packet size of "packet_size_ms". | 125 // Create 10ms audio data blocks for a total packet size of "packet_size_ms". |
119 std::unique_ptr<test::AudioLoop> Create10msAudioBlocks( | 126 std::unique_ptr<test::AudioLoop> Create10msAudioBlocks( |
120 const std::unique_ptr<AudioEncoderOpus>& encoder, | 127 const std::unique_ptr<AudioEncoderOpus>& encoder, |
121 int packet_size_ms) { | 128 int packet_size_ms) { |
122 const std::string file_name = | 129 const std::string file_name = |
123 test::ResourcePath("audio_coding/testfile32kHz", "pcm"); | 130 test::ResourcePath("audio_coding/testfile32kHz", "pcm"); |
124 | 131 |
125 std::unique_ptr<test::AudioLoop> speech_data(new test::AudioLoop()); | 132 std::unique_ptr<test::AudioLoop> speech_data(new test::AudioLoop()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 EXPECT_EQ(AudioEncoderOpus::kAudio, states.encoder->application()); | 187 EXPECT_EQ(AudioEncoderOpus::kAudio, states.encoder->application()); |
181 // Turn off DTX. | 188 // Turn off DTX. |
182 EXPECT_TRUE(states.encoder->SetDtx(false)); | 189 EXPECT_TRUE(states.encoder->SetDtx(false)); |
183 } | 190 } |
184 | 191 |
185 TEST(AudioEncoderOpusTest, | 192 TEST(AudioEncoderOpusTest, |
186 OnReceivedUplinkBandwidthWithoutAudioNetworkAdaptor) { | 193 OnReceivedUplinkBandwidthWithoutAudioNetworkAdaptor) { |
187 auto states = CreateCodec(1); | 194 auto states = CreateCodec(1); |
188 // Constants are replicated from audio_states.encoderopus.cc. | 195 // Constants are replicated from audio_states.encoderopus.cc. |
189 const int kMinBitrateBps = 6000; | 196 const int kMinBitrateBps = 6000; |
190 const int kMaxBitrateBps = 512000; | 197 const int kMaxBitrateBps = 510000; |
191 // Set a too low bitrate. | 198 // Set a too low bitrate. |
192 states.encoder->OnReceivedUplinkBandwidth(kMinBitrateBps - 1, | 199 states.encoder->OnReceivedUplinkBandwidth(kMinBitrateBps - 1, |
193 rtc::Optional<int64_t>()); | 200 rtc::Optional<int64_t>()); |
194 EXPECT_EQ(kMinBitrateBps, states.encoder->GetTargetBitrate()); | 201 EXPECT_EQ(kMinBitrateBps, states.encoder->GetTargetBitrate()); |
195 // Set a too high bitrate. | 202 // Set a too high bitrate. |
196 states.encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps + 1, | 203 states.encoder->OnReceivedUplinkBandwidth(kMaxBitrateBps + 1, |
197 rtc::Optional<int64_t>()); | 204 rtc::Optional<int64_t>()); |
198 EXPECT_EQ(kMaxBitrateBps, states.encoder->GetTargetBitrate()); | 205 EXPECT_EQ(kMaxBitrateBps, states.encoder->GetTargetBitrate()); |
199 // Set the minimum rate. | 206 // Set the minimum rate. |
200 states.encoder->OnReceivedUplinkBandwidth(kMinBitrateBps, | 207 states.encoder->OnReceivedUplinkBandwidth(kMinBitrateBps, |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 EXPECT_EQ(kTargetBitrateBps - | 418 EXPECT_EQ(kTargetBitrateBps - |
412 8 * static_cast<int>(kOverheadBytesPerPacket) * packet_rate, | 419 8 * static_cast<int>(kOverheadBytesPerPacket) * packet_rate, |
413 states.encoder->GetTargetBitrate()); | 420 states.encoder->GetTargetBitrate()); |
414 } | 421 } |
415 | 422 |
416 TEST(AudioEncoderOpusTest, BitrateBounded) { | 423 TEST(AudioEncoderOpusTest, BitrateBounded) { |
417 test::ScopedFieldTrials override_field_trials( | 424 test::ScopedFieldTrials override_field_trials( |
418 "WebRTC-SendSideBwe-WithOverhead/Enabled/"); | 425 "WebRTC-SendSideBwe-WithOverhead/Enabled/"); |
419 | 426 |
420 constexpr int kMinBitrateBps = 6000; | 427 constexpr int kMinBitrateBps = 6000; |
421 constexpr int kMaxBitrateBps = 512000; | 428 constexpr int kMaxBitrateBps = 510000; |
422 | 429 |
423 auto states = CreateCodec(2); | 430 auto states = CreateCodec(2); |
424 | 431 |
425 constexpr size_t kOverheadBytesPerPacket = 64; | 432 constexpr size_t kOverheadBytesPerPacket = 64; |
426 states.encoder->OnReceivedOverhead(kOverheadBytesPerPacket); | 433 states.encoder->OnReceivedOverhead(kOverheadBytesPerPacket); |
427 | 434 |
428 int packet_rate = rtc::CheckedDivExact(48000, kDefaultOpusSettings.pacsize); | 435 int packet_rate = rtc::CheckedDivExact(48000, kDefaultOpusSettings.pacsize); |
429 | 436 |
430 // Set a target rate that is smaller than |kMinBitrateBps| when overhead is | 437 // Set a target rate that is smaller than |kMinBitrateBps| when overhead is |
431 // subtracted. The eventual codec rate should be bounded by |kMinBitrateBps|. | 438 // subtracted. The eventual codec rate should be bounded by |kMinBitrateBps|. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 } | 546 } |
540 | 547 |
541 // Should encode now. | 548 // Should encode now. |
542 states.encoder->Encode(rtp_timestamp, audio_frames->GetNextBlock(), | 549 states.encoder->Encode(rtp_timestamp, audio_frames->GetNextBlock(), |
543 &encoded); | 550 &encoded); |
544 EXPECT_GT(encoded.size(), 0u); | 551 EXPECT_GT(encoded.size(), 0u); |
545 encoded.Clear(); | 552 encoded.Clear(); |
546 } | 553 } |
547 } | 554 } |
548 | 555 |
| 556 TEST(AudioEncoderOpusTest, TestConfigDefaults) { |
| 557 const AudioEncoderOpus::Config config = |
| 558 AudioEncoderOpus::CreateConfig(0, {"opus", 48000, 2}); |
| 559 |
| 560 EXPECT_EQ(48000, config.max_playback_rate_hz); |
| 561 EXPECT_EQ(1u, config.num_channels); |
| 562 EXPECT_FALSE(config.fec_enabled); |
| 563 EXPECT_FALSE(config.dtx_enabled); |
| 564 EXPECT_EQ(20, config.frame_size_ms); |
| 565 } |
| 566 |
| 567 TEST(AudioEncoderOpusTest, TestConfigFromParams) { |
| 568 AudioEncoderOpus::Config config; |
| 569 |
| 570 config = CreateConfigWithParameters({{"stereo", "0"}}); |
| 571 EXPECT_EQ(1U, config.num_channels); |
| 572 |
| 573 config = CreateConfigWithParameters({{"stereo", "1"}}); |
| 574 EXPECT_EQ(2U, config.num_channels); |
| 575 |
| 576 config = CreateConfigWithParameters({{"useinbandfec", "0"}}); |
| 577 EXPECT_EQ(false, config.fec_enabled); |
| 578 |
| 579 config = CreateConfigWithParameters({{"useinbandfec", "1"}}); |
| 580 EXPECT_EQ(true, config.fec_enabled); |
| 581 |
| 582 config = CreateConfigWithParameters({{"usedtx", "0"}}); |
| 583 EXPECT_EQ(false, config.dtx_enabled); |
| 584 |
| 585 config = CreateConfigWithParameters({{"usedtx", "1"}}); |
| 586 EXPECT_EQ(true, config.dtx_enabled); |
| 587 |
| 588 config = CreateConfigWithParameters({{"maxplaybackrate", "12345"}}); |
| 589 EXPECT_EQ(12345, config.max_playback_rate_hz); |
| 590 |
| 591 config = CreateConfigWithParameters({{"maxaveragebitrate", "96000"}}); |
| 592 EXPECT_EQ(96000, config.bitrate_bps); |
| 593 |
| 594 config = CreateConfigWithParameters({{"maxptime", "40"}}); |
| 595 for (int frame_length : config.supported_frame_lengths_ms) { |
| 596 EXPECT_LE(frame_length, 40); |
| 597 } |
| 598 |
| 599 config = CreateConfigWithParameters({{"minptime", "40"}}); |
| 600 for (int frame_length : config.supported_frame_lengths_ms) { |
| 601 EXPECT_GE(frame_length, 40); |
| 602 } |
| 603 |
| 604 config = CreateConfigWithParameters({{"ptime", "40"}}); |
| 605 EXPECT_EQ(40, config.frame_size_ms); |
| 606 |
| 607 constexpr int kMinSupportedFrameLength = 10; |
| 608 constexpr int kMaxSupportedFrameLength = |
| 609 WEBRTC_OPUS_SUPPORT_120MS_PTIME ? 120 : 60; |
| 610 |
| 611 config = CreateConfigWithParameters({{"ptime", "1"}}); |
| 612 EXPECT_EQ(kMinSupportedFrameLength, config.frame_size_ms); |
| 613 |
| 614 config = CreateConfigWithParameters({{"ptime", "2000"}}); |
| 615 EXPECT_EQ(kMaxSupportedFrameLength, config.frame_size_ms); |
| 616 } |
| 617 |
| 618 TEST(AudioEncoderOpusTest, TestConfigFromInvalidParams) { |
| 619 const webrtc::SdpAudioFormat format("opus", 48000, 2); |
| 620 const AudioEncoderOpus::Config default_config = |
| 621 AudioEncoderOpus::CreateConfig(0, format); |
| 622 const std::vector<int> default_supported_frame_lengths_ms({20, 60}); |
| 623 |
| 624 AudioEncoderOpus::Config config; |
| 625 config = CreateConfigWithParameters({{"stereo", "invalid"}}); |
| 626 EXPECT_EQ(default_config.num_channels, config.num_channels); |
| 627 |
| 628 config = CreateConfigWithParameters({{"useinbandfec", "invalid"}}); |
| 629 EXPECT_EQ(default_config.fec_enabled, config.fec_enabled); |
| 630 |
| 631 config = CreateConfigWithParameters({{"usedtx", "invalid"}}); |
| 632 EXPECT_EQ(default_config.dtx_enabled, config.dtx_enabled); |
| 633 |
| 634 config = CreateConfigWithParameters({{"maxplaybackrate", "0"}}); |
| 635 EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz); |
| 636 |
| 637 config = CreateConfigWithParameters({{"maxplaybackrate", "-23"}}); |
| 638 EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz); |
| 639 |
| 640 config = CreateConfigWithParameters({{"maxplaybackrate", "not a number!"}}); |
| 641 EXPECT_EQ(default_config.max_playback_rate_hz, config.max_playback_rate_hz); |
| 642 |
| 643 config = CreateConfigWithParameters({{"maxaveragebitrate", "0"}}); |
| 644 EXPECT_EQ(6000, config.bitrate_bps); |
| 645 |
| 646 config = CreateConfigWithParameters({{"maxaveragebitrate", "-1000"}}); |
| 647 EXPECT_EQ(6000, config.bitrate_bps); |
| 648 |
| 649 config = CreateConfigWithParameters({{"maxaveragebitrate", "1024000"}}); |
| 650 EXPECT_EQ(510000, config.bitrate_bps); |
| 651 |
| 652 config = CreateConfigWithParameters({{"maxaveragebitrate", "not a number!"}}); |
| 653 EXPECT_EQ(default_config.bitrate_bps, config.bitrate_bps); |
| 654 |
| 655 config = CreateConfigWithParameters({{"maxptime", "invalid"}}); |
| 656 EXPECT_EQ(default_supported_frame_lengths_ms, |
| 657 config.supported_frame_lengths_ms); |
| 658 |
| 659 config = CreateConfigWithParameters({{"minptime", "invalid"}}); |
| 660 EXPECT_EQ(default_supported_frame_lengths_ms, |
| 661 config.supported_frame_lengths_ms); |
| 662 |
| 663 config = CreateConfigWithParameters({{"ptime", "invalid"}}); |
| 664 EXPECT_EQ(default_supported_frame_lengths_ms, |
| 665 config.supported_frame_lengths_ms); |
| 666 } |
| 667 |
| 668 // Test that bitrate will be overridden by the "maxaveragebitrate" parameter. |
| 669 // Also test that the "maxaveragebitrate" can't be set to values outside the |
| 670 // range of 6000 and 510000 |
| 671 TEST(AudioEncoderOpusTest, SetSendCodecOpusMaxAverageBitrate) { |
| 672 // Ignore if less than 6000. |
| 673 const AudioEncoderOpus::Config config1 = AudioEncoderOpus::CreateConfig( |
| 674 0, {"opus", 48000, 2, {{"maxaveragebitrate", "5999"}}}); |
| 675 EXPECT_EQ(6000, config1.bitrate_bps); |
| 676 |
| 677 // Ignore if larger than 510000. |
| 678 const AudioEncoderOpus::Config config2 = AudioEncoderOpus::CreateConfig( |
| 679 0, {"opus", 48000, 2, {{"maxaveragebitrate", "510001"}}}); |
| 680 EXPECT_EQ(510000, config2.bitrate_bps); |
| 681 |
| 682 const AudioEncoderOpus::Config config3 = AudioEncoderOpus::CreateConfig( |
| 683 0, {"opus", 48000, 2, {{"maxaveragebitrate", "200000"}}}); |
| 684 EXPECT_EQ(200000, config3.bitrate_bps); |
| 685 } |
| 686 |
| 687 // Test maxplaybackrate <= 8000 triggers Opus narrow band mode. |
| 688 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateNb) { |
| 689 auto config = CreateConfigWithParameters({{"maxplaybackrate", "8000"}}); |
| 690 EXPECT_EQ(8000, config.max_playback_rate_hz); |
| 691 EXPECT_EQ(12000, config.bitrate_bps); |
| 692 |
| 693 config = CreateConfigWithParameters({{"maxplaybackrate", "8000"}, |
| 694 {"stereo", "1"}}); |
| 695 EXPECT_EQ(8000, config.max_playback_rate_hz); |
| 696 EXPECT_EQ(24000, config.bitrate_bps); |
| 697 } |
| 698 |
| 699 // Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode. |
| 700 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateMb) { |
| 701 auto config = CreateConfigWithParameters({{"maxplaybackrate", "8001"}}); |
| 702 EXPECT_EQ(8001, config.max_playback_rate_hz); |
| 703 EXPECT_EQ(20000, config.bitrate_bps); |
| 704 |
| 705 config = CreateConfigWithParameters({{"maxplaybackrate", "8001"}, |
| 706 {"stereo", "1"}}); |
| 707 EXPECT_EQ(8001, config.max_playback_rate_hz); |
| 708 EXPECT_EQ(40000, config.bitrate_bps); |
| 709 } |
| 710 |
| 711 // Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode. |
| 712 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateWb) { |
| 713 auto config = CreateConfigWithParameters({{"maxplaybackrate", "12001"}}); |
| 714 EXPECT_EQ(12001, config.max_playback_rate_hz); |
| 715 EXPECT_EQ(20000, config.bitrate_bps); |
| 716 |
| 717 config = CreateConfigWithParameters({{"maxplaybackrate", "12001"}, |
| 718 {"stereo", "1"}}); |
| 719 EXPECT_EQ(12001, config.max_playback_rate_hz); |
| 720 EXPECT_EQ(40000, config.bitrate_bps); |
| 721 } |
| 722 |
| 723 // Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode. |
| 724 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateSwb) { |
| 725 auto config = CreateConfigWithParameters({{"maxplaybackrate", "16001"}}); |
| 726 EXPECT_EQ(16001, config.max_playback_rate_hz); |
| 727 EXPECT_EQ(32000, config.bitrate_bps); |
| 728 |
| 729 config = CreateConfigWithParameters({{"maxplaybackrate", "16001"}, |
| 730 {"stereo", "1"}}); |
| 731 EXPECT_EQ(16001, config.max_playback_rate_hz); |
| 732 EXPECT_EQ(64000, config.bitrate_bps); |
| 733 } |
| 734 |
| 735 // Test 24000 < maxplaybackrate triggers Opus full band mode. |
| 736 TEST(AudioEncoderOpusTest, SetMaxPlaybackRateFb) { |
| 737 auto config = CreateConfigWithParameters({{"maxplaybackrate", "24001"}}); |
| 738 EXPECT_EQ(24001, config.max_playback_rate_hz); |
| 739 EXPECT_EQ(32000, config.bitrate_bps); |
| 740 |
| 741 config = CreateConfigWithParameters({{"maxplaybackrate", "24001"}, |
| 742 {"stereo", "1"}}); |
| 743 EXPECT_EQ(24001, config.max_playback_rate_hz); |
| 744 EXPECT_EQ(64000, config.bitrate_bps); |
| 745 } |
| 746 |
549 } // namespace webrtc | 747 } // namespace webrtc |
OLD | NEW |